We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
需求:在网站上想评论一篇文章,而评论文章是要用户注册与登录的,那么怎么免去这麻烦的步骤呢?答案是通过第三方授权登录。本文讲解的就是 github 授权登录的教程。
效果体验地址: http://biaochenxuying.cn
先来看下 github 授权的完整流程图 1:
或者看下 github 授权的完整流程图 2:
首先我们必须登录上 github 申请一个 OAuth App,步骤如下:
具体实践如下:
流程也可看 GitHub 设置的官方文档-Registering OAuth Apps。
github 文档:building-oauth-apps/authorizing-oauth-apps
授权登录的主要 3 个步骤:
笔者这次实践中,项目是采用前后端分离的,所以第 1 步在前端实现,而第 2 步和第 3 步是在后端实现的,因为第 2 个接口里面需要Client_secret 这个参数,而且第 3 步获取的用户信息在后端保存到数据库。
笔者项目的技术是 react。
// config.js // ***** 处请填写你申请的 OAuth App 的真实内容 const config = { 'oauth_uri': 'https://github.com/login/oauth/authorize', 'redirect_uri': 'http://biaochenxuying.cn/', 'client_id': '*****', 'client_secret': '*******', }; // 本地开发环境下 if (process.env.NODE_ENV === 'development') { config.redirect_uri = "http://localhost:3001/" config.client_id = "******" config.client_secret = "*****" } export default config;
代码参考 config.js
redirect_uri 回调地址是分环境的,所以我是新建了两个 OAuth App 的,一个用于线上生产环境,一个用于本地开发环境。
一般来说,登录的页面应该是独立的,对应相应的路由 /login , 但是本项目的登录 login 组件是 nav 组件的子组件,nav 是个全局用的组件, 所以回调地址就写了 http://biaochenxuying.cn/。
// login.js // html <Button style={{ width: '100%' }} onClick={this.handleOAuth} > github 授权登录 </Button> // js handleOAuth(){ // 保存授权前的页面链接 window.localStorage.preventHref = window.location.href // window.location.href = 'https://github.com/login/oauth/authorize?client_id=***&redirect_uri=http://biaochenxuying.cn/' window.location.href = `${config.oauth_uri}?client_id=${config.client_id}&redirect_uri=${config.redirect_uri}` }
代码参考 login.js
// nav.js componentDidMount() { // console.log('code :', getQueryStringByName('code')); const code = getQueryStringByName('code') if (code) { this.setState( { code }, () => { if (!this.state.code) { return; } this.getUser(this.state.code); }, ); } } componentWillReceiveProps(nextProps) { const code = getQueryStringByName('code') if (code) { this.setState( { code }, () => { if (!this.state.code) { return; } this.getUser(this.state.code); }, ); } } getUser(code) { https .post( urls.getUser, { code, }, { withCredentials: true }, ) .then(res => { // console.log('res :', res.data); if (res.status === 200 && res.data.code === 0) { this.props.loginSuccess(res.data); let userInfo = { _id: res.data.data._id, name: res.data.data.name, }; window.sessionStorage.userInfo = JSON.stringify(userInfo); message.success(res.data.message, 1); this.handleLoginCancel(); // 跳转到之前授权前的页面 const href = window.localStorage.preventHref if(href){ window.location.href = href } } else { this.props.loginFailure(res.data.message); message.error(res.data.message, 1); } }) .catch(err => { console.log(err); }); }
参考 nav.js
笔者项目的后端采用的技术是 node.js 和 express。
// app.config.js exports.GITHUB = { oauth_uri: 'https://github.com/login/oauth/authorize', access_token_url: 'https://github.com/login/oauth/access_token', // 获取 github 用户信息 url // eg: https://api.github.com/user?access_token=******&scope=&token_type=bearer user_url: 'https://api.github.com/user', // 生产环境 redirect_uri: 'http://biaochenxuying.cn/', client_id: '*****', client_secret: '*****', // // 开发环境 // redirect_uri: "http://localhost:3001/", // client_id: "*****", // client_secret: "*****", };
代码参考 app.config.js
// 路由文件 user.js const fetch = require('node-fetch'); const CONFIG = require('../app.config.js'); const User = require('../models/user'); // 第三方授权登录的用户信息 exports.getUser = (req, res) => { let { code } = req.body; if (!code) { responseClient(res, 400, 2, 'code 缺失'); return; } let path = CONFIG.GITHUB.access_token_url; const params = { client_id: CONFIG.GITHUB.client_id, client_secret: CONFIG.GITHUB.client_secret, code: code, }; // console.log(code); fetch(path, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(params), }) .then(res1 => { return res1.text(); }) .then(body => { const args = body.split('&'); let arg = args[0].split('='); const access_token = arg[1]; // console.log("body:",body); console.log('access_token:', access_token); return access_token; }) .then(async token => { const url = CONFIG.GITHUB.user_url + '?access_token=' + token; console.log('url:', url); await fetch(url) .then(res2 => { console.log('res2 :', res2); return res2.json(); }) .then(response => { console.log('response ', response); if (response.id) { //验证用户是否已经在数据库中 User.findOne({ github_id: response.id }) .then(userInfo => { // console.log('userInfo :', userInfo); if (userInfo) { //登录成功后设置session req.session.userInfo = userInfo; responseClient(res, 200, 0, '授权登录成功', userInfo); } else { let obj = { github_id: response.id, email: response.email, password: response.login, type: 2, avatar: response.avatar_url, name: response.login, location: response.location, }; //注册到数据库 let user = new User(obj); user.save().then(data => { // console.log('data :', data); req.session.userInfo = data; responseClient(res, 200, 0, '授权登录成功', data); }); } }) .catch(err => { responseClient(res); return; }); } else { responseClient(res, 400, 1, '授权登录失败', response); } }); }) .catch(e => { console.log('e:', e); }); };
代码参考 user.js
至于拿到 github 的用户信息后,是注册到 user 表,还是保存到另外一张 oauth 映射表,这个得看自己项目的情况。
从 github 拿到的用户信息如下图:
最终效果:
参与文章:
https://www.jianshu.com/p/a9c0b277a3b3
https://blog.csdn.net/zhuming3834/article/details/77649960
第三方授权登录的时候,第三方的用户信息是存数据库原有的 user 表还是新建一张表呢 ?
答案:这得看具体项目了,做法多种,请看下文。
第三方授权登录之后,第三方用户信息一般都会返回用户唯一的标志 openid 或者 unionid 或者 id,具体是什么得看第三方,比如 github 的是 id
第一种:如果网站 没有 注册功能的,直接通过第三方授权登录,授权成功之后,可以直接把第三的用户信息 注册 保存到自己数据库的 user 表里面。典型的例子就是 微信公众号的授权登录。
第二种:如果网站 有 注册功能的,也可以通过第三方授权登录,授权成功之后,也可以直接把第三的用户信息 注册 保存到自己数据库的 user 表里面(但是密码是后端自动生成的,用户也不知道,只能用第三方授权登录),这样子的第三方的用户和原生注册的用户信息都在同一张表了,这种情况得看自己项目的具体情况。笔者的博客网站暂时就采用了这种方式。
现实中很多网站都有多种账户登录方式,比如可以用网站的注册 id 登录,还可以用手机号登录,可以用 QQ 登录等等。数据库中都是有映射关系,QQ、手机号等都是映射在网站的注册 id 上。保证不管用什么方式登录,只要去查映射关系,发现是映射在网站注册的哪个 id 上,就让哪个 id 登录成功。
建立一个 oauth 表,一个 id 列,记录对应的用户注册表的 id,然后你有多少个第三方登陆功能,你就建立多少列,记录第三方登陆接口返回的 openid;第三方登陆的时候,通过这个表的记录的 openid 获取 id 信息,如果存在通过 id 读取注册表然后用 session 记录相关信息。不存在就转向用户登陆/注册界面要用户输入本站注册的账户进行 openid 绑定或者新注册账户信息进行绑定。
具体代码实践请参考文章:
1. 第三方登录用户信息表设计
2. 浅谈数据库用户表结构设计,第三方登录
笔者的 github 博客地址:https://github.com/biaochenxuying/blog
The text was updated successfully, but these errors were encountered:
biaochenxuying
No branches or pull requests
需求:在网站上想评论一篇文章,而评论文章是要用户注册与登录的,那么怎么免去这麻烦的步骤呢?答案是通过第三方授权登录。本文讲解的就是 github 授权登录的教程。
效果体验地址: http://biaochenxuying.cn
1. github 第三方授权登录教程
先来看下 github 授权的完整流程图 1:
或者看下 github 授权的完整流程图 2:
1.1 申请一个 OAuth App
首先我们必须登录上 github 申请一个 OAuth App,步骤如下:
具体实践如下:
流程也可看 GitHub 设置的官方文档-Registering OAuth Apps。
1.2 授权登录
github 文档:building-oauth-apps/authorizing-oauth-apps
授权登录的主要 3 个步骤:
笔者这次实践中,项目是采用前后端分离的,所以第 1 步在前端实现,而第 2 步和第 3 步是在后端实现的,因为第 2 个接口里面需要Client_secret 这个参数,而且第 3 步获取的用户信息在后端保存到数据库。
1.3. 代码实现
1.3.1 前端
笔者项目的技术是 react。
代码参考 config.js
redirect_uri 回调地址是分环境的,所以我是新建了两个 OAuth App 的,一个用于线上生产环境,一个用于本地开发环境。
一般来说,登录的页面应该是独立的,对应相应的路由 /login , 但是本项目的登录 login 组件是 nav 组件的子组件,nav 是个全局用的组件, 所以回调地址就写了 http://biaochenxuying.cn/。
代码参考 login.js
参考 nav.js
1.3.2 后端
笔者项目的后端采用的技术是 node.js 和 express。
代码参考 app.config.js
代码参考 user.js
至于拿到 github 的用户信息后,是注册到 user 表,还是保存到另外一张 oauth 映射表,这个得看自己项目的情况。
从 github 拿到的用户信息如下图:
最终效果:
参与文章:
https://www.jianshu.com/p/a9c0b277a3b3
https://blog.csdn.net/zhuming3834/article/details/77649960
2. 如何设计第三方授权登录的用户表
第三方授权登录的时候,第三方的用户信息是存数据库原有的 user 表还是新建一张表呢 ?
答案:这得看具体项目了,做法多种,请看下文。
第三方授权登录之后,第三方用户信息一般都会返回用户唯一的标志 openid 或者 unionid 或者 id,具体是什么得看第三方,比如 github 的是 id
第一种:如果网站 没有 注册功能的,直接通过第三方授权登录,授权成功之后,可以直接把第三的用户信息 注册 保存到自己数据库的 user 表里面。典型的例子就是 微信公众号的授权登录。
第二种:如果网站 有 注册功能的,也可以通过第三方授权登录,授权成功之后,也可以直接把第三的用户信息 注册 保存到自己数据库的 user 表里面(但是密码是后端自动生成的,用户也不知道,只能用第三方授权登录),这样子的第三方的用户和原生注册的用户信息都在同一张表了,这种情况得看自己项目的具体情况。笔者的博客网站暂时就采用了这种方式。
现实中很多网站都有多种账户登录方式,比如可以用网站的注册 id 登录,还可以用手机号登录,可以用 QQ 登录等等。数据库中都是有映射关系,QQ、手机号等都是映射在网站的注册 id 上。保证不管用什么方式登录,只要去查映射关系,发现是映射在网站注册的哪个 id 上,就让哪个 id 登录成功。
建立一个 oauth 表,一个 id 列,记录对应的用户注册表的 id,然后你有多少个第三方登陆功能,你就建立多少列,记录第三方登陆接口返回的 openid;第三方登陆的时候,通过这个表的记录的 openid 获取 id 信息,如果存在通过 id 读取注册表然后用 session 记录相关信息。不存在就转向用户登陆/注册界面要用户输入本站注册的账户进行 openid 绑定或者新注册账户信息进行绑定。
具体代码实践请参考文章:
1. 第三方登录用户信息表设计
2. 浅谈数据库用户表结构设计,第三方登录
4. 最后
The text was updated successfully, but these errors were encountered: