在客户端应用程序中实现Github OAuth的正确方法?

时间:2019-03-03 16:48:34

标签: javascript node.js reactjs oauth

我正在将OAuth添加到我的github客户端应用程序中。我已经成功地返回了最终的身份验证令牌,但我感觉自己像黑了我的工作流程。

当前架构流程:

1)用户单击组件上的href链接以击打初始OAUTH路线

2)从Github检索令牌以获取用户身份

3)Github重定向到我的服务器路由,并且我的服务器路由通过POST/access_token和{{1}向client_secret请求页面发送了另外一个id }。

4)最后,我从上述路由重定向回我的UI,并在此过程中设置了URL参数

5)在code中,我从componentDidMount剥离最终的身份验证令牌,并将其设置为我的状态

  

注意:我计划稍后将令牌存储在Redux中,但这是基础   我在做什么的水平。

实际代码

服务器

window.url

UI身份验证组件

app.get("/login", async (req, res) => {
  // Get the identity token from GitHub origin
  return await axios
    .post("https://github.com/login/oauth/access_token", {
      code: req.query.code,
      client_id: process.env.CLIENT_ID,
      client_secret: process.env.CLIENT_SECRET
    })
    .then(async resp => {
      // Little hack to parse out the query params into an object 
      let data = await url.parse("http://parse.com?" + resp.data, {
        parseQueryString: true
      }).query;

      res.redirect(
        url.format({
          pathname: Environment.getUrl(),
          query: {
            token: data.access_token
          }
        })
      );
    });
});

问题

1)我无法弄清的一件事是使export default class GithubAuthentication extends React.Component { state = { authToken: "DATA" }; componentDidMount() { let currUrl = window.location.href; this.setState({ authToken: currUrl.split("token=")[1] }); } render() { return ( <React.Fragment> <a href="https://github.com/login/oauth/authorize?client_id=b5cd37110eb31620aad7"> {this.state.authToken ? "Logout" : "Login With Github"} </a> <span>{this.state.authToken}</span> </React.Fragment> ); } } 链接为受控组件,并实际上使用诸如hrefSuperAgent之类的东西来访问auth URL。相反,我被迫使用此Axios链接,不确定原因。

2)这实际上是获取最终auth令牌的明智流程吗?

2 个答案:

答案 0 :(得分:1)

关于问题2,从安全角度来看,最好将访问令牌保留在服务器端,而永远不要将令牌发送到客户端。

我找不到好的书面资源,所以我想分享此视频,该视频总结了如何清楚地处理访问令牌。

https://www.youtube.com/watch?v=CHzERullHe8&list=PL78z2Z3ZApYcKb-GDQt6ikdN2EDqmKJrT&index=12&t=419s

远离视频

  • 我们仍然没有一种将令牌安全存储在浏览器中的好方法
  • 通过将访问令牌存储在服务器端并使用会话cookie,可以最大程度地降低访问令牌被泄露的风险。

要实际实现此流程,可以使用cookie-session生成会话。您还可以使用github-passport简化实现。

https://github.com/expressjs/cookie-session https://github.com/jaredhanson/passport-github

答案 1 :(得分:0)

1)我认为您应该重新组织应用程序,以便可以使用组件而不是href链接。您将基于state属性的值知道是否通过了身份验证。此值可以作为prop传递到组件,在该组件中将放置验证的逻辑? “注销”:“登录”或其他任何内容。

2)流程还可以,但是您必须确保对令牌进行服务器端验证,因为只需翻转UI上的开关,就可以很容易地进行身份验证。