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

Javascript 在客户端应用程序中实现Github OAuth的正确方法?,javascript,node.js,reactjs,oauth,Javascript,Node.js,Reactjs,Oauth,我正在将OAuth添加到我的github客户端应用程序中。我已经成功返回了最终的身份验证令牌,但我觉得我好像侵入了我的工作流 当前架构流程: 1) 用户单击组件的链接以点击初始OAUTH路由 2) 从Github检索用户标识的令牌 3) Github重定向到我的服务器路由,我的服务器路由使用上面步骤中的客户端密钥、id和代码向/access\u令牌请求页面发送额外的POST 4) 最后,我从上面的路由重定向回我的UI,并在这个过程中设置一个URL参数 5) 在componentDidMount中

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

当前架构流程: 1) 用户单击组件的链接以点击初始OAUTH路由

2) 从Github检索用户标识的令牌

3) Github重定向到我的服务器路由,我的服务器路由使用上面步骤中的
客户端密钥
id
代码
/access\u令牌
请求页面发送额外的
POST

4) 最后,我从上面的路由重定向回我的UI,并在这个过程中设置一个URL参数

5) 在
componentDidMount
中,我从
window.url
中取出最终的身份验证令牌,并将其设置为我的状态

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

实际代码 服务器 用户界面验证组件
导出默认类github.Component{
状态={
authToken:“数据”
};
componentDidMount(){
让currUrl=window.location.href;
this.setState({authToken:currUrl.split(“token=)[1]});
}
render(){
返回(
{this.state.authToken}
);
}
}
问题 1) 有一件事我没能弄明白,那就是把
href
链接成一个受控组件,然后用
超级代理
Axios
之类的东西点击auth URL。相反,我不得不使用这个
href
链接,不知道为什么

2) 这实际上是获取最终身份验证令牌的合理流程吗?

1)我认为您应该重新组织应用程序,以便使用组件而不是href链接。您将根据state属性上的值知道是否对您进行了身份验证。这个值可以作为prop传递给组件,您可以将authenticated的逻辑放在组件中?“注销”:“登录”或其他任何内容


2) 流程正常,但您必须确保对令牌进行服务器端验证,因为只需翻转UI上的开关并假装您很容易通过身份验证即可。

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

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

从视频中删除

  • 我们仍然没有在浏览器上安全存储令牌的好方法
  • 通过将访问令牌存储在服务器端并使用会话cookie,您可以将访问令牌被破坏的风险降至最低
要实际实现此流,可以使用cookie会话生成会话。您还可以使用github passport来简化实现


我在使用组件而不是href时遇到了跨源问题。不太清楚发生这种情况的原因。如果您向另一台服务器发出js调用,并且该服务器不允许来自默认打开的未知应用程序的未经请求的调用,则会发生CORS问题,因此您的服务器应在
Access Control allow Origin
标题中允许来自客户端域的请求
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
          }
        })
      );
    });
});
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>
    );
  }
}