需求:想在网站上评论一篇文章,而评论文章需要用户注册登录,如何避免这个麻烦步?答案是通过第三方授权登录。本文讲解github授权登录教程。效果体验地址:http://biaochenxuying.cn1。github第三方授权登录教程先看github授权完整流程图1:或者看github授权完整流程图2:1.1申请OAuthApp,首先要登录申请OAuthAppgithub上,步骤如下:登录github点击头像下的Settings->Developersettings,在右侧填写NewOAuthApp的applicationapp的相关配置。关键配置项包括2个HomepageURL,这是后面需要授权的URL。你可以理解为你的项目根目录地址AuthorizationcallbackURL授权成功后的回调地址,这个很重要,这是你拿到授权码的时候给你的回调地址。具体做法如下:先登录自己的GitHub账号,然后点击进入Settings。单击OAuth应用程序,注册新应用程序或新OAuth应用程序。输入信息。应用信息的描述。该过程也可以在GitHub设置的官方文档-RegisteringOAuthApps中看到。1.2授权登录github文档:building-oauth-apps/authorizing-oauth-apps授权登录主要三步:web重定向http://github.com/login/oauth...根据code获取access_token根据获取access_token用户信息本次实践中,项目是前后端分离的,所以第一步在前端实现,而第二步和第三步在后端实现,因为第二个接口需要参数Client_secret.并将步骤3中获取的用户信息保存到后台的数据库中。1.3.代码实现1.3.1前端作者项目的技术是react。//config.js//*****请填写您申请的OAuthApp的真实内容constconfig={'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="*****"}导出默认配置;代码参考config.jsredirect_uri回调地址分环境,所以我新建了两个OAuthApp,一个用于线上生产环境,一个用于本地开发环境。一般来说,登录页面应该是独立的,对应相应的路由/login,但是本项目的登录组件是nav组件的子组件,而nav是全局组件,所以回调地址写成http://biaochenxuying.cn/.所以点击跳转是在login.js中写的;获取授权后获取代码,在nav.js中编写。nav.js获取code值后,请求后台接口,后台接口返回用户信息。其中,后台需要去github上获取access_token获取代码,然后根据access_token去github上获取用户的信息。//login.js//htmlgithub授权登录//jshandleOAuth(){//保存授权前的页面链接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.jscomponentDidMount(){//console.日志('代码:',getQueryStringByName('代码'));constcode=getQueryStringByName('code')if(code){this.setState({code},()=>{if(!this.state.code){return;}this.getUser(this.state.code);},);}}componentWillReceiveProps(nextProps){constcode=getQueryStringByName('code')if(code){this.setState({代码},()=>{如果(!this.state.code){返回;}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);letuserInfo={_id:res.data.data._id,name:res.data.data.name,};window.sessionStorage.userInfo=JSON.stringify(userInfo);message.success(res.data.message,1);this.handleLoginCancel();//跳转到授权前的页面consthref=window.localStorage.preventHrefif(href){window.location.href=href}}else{this.props.loginFailure(res.data.message);message.error(res.data.message,1);}}).catch(err=>{console.log(err);});}参考nav.js1.3.2Backend采用笔者项目的后端技术是node.js和expressbackend从前端拿到code后,要到github上去获取access_token,以及然后去github上根据access_token获取用户的信息。然后通过注册将要使用的用户信息保存到数据库中,再将用户信息返回给前端。//app.config.jsexports.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=beareruser_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.jsconstfetch=require('node-fetch');constCONFIG=require('../app.config.js');constUser=require('../models/user');//第三方授权登录导出的用户信息.getUser=(req,res)=>{let{code}=req.body;if(!code){responseClient(res,400,2,'代码丢失');返回;}让路径=CONFIG.GITHUB。access_token_url;constparams={client_id:CONFIG.GITHUB.client_id,client_secrett:CONFIG.GITHUB.client_secret,code:code,};//控制台日志(代码);fetch(path,{method:'POST',headers:{'Content-Type':'application/json',},body:JSON.stringify(params),}).then(res1=>{返回res1.text();}).then(body=>{constargs=body.split('&');letarg=args[0].split('=');constaccess_token=arg[1];//控制台.log("body:",body);console.log('access_token:',access_token);returnaccess_token;}).then(asynctoken=>{consturl=CONFIG.GITHUB.user_url+'?access_token='+token;console.log('url:',url);awaitfetch(url).then(res2=>{console.log('res2:',res2);returnres2.json();}).then(response=>{console.log('response',response);if(response.id){//验证用户是否已经在数据库中User.findOne({github_id:response.id}).then(userInfo=>{//console.log('userInfo:',userInfo);if(userInfo){//登录成功后设置sessionreq.session.userInfo=userInfo;responseClient(res,200,0,'授权登录成功',userInfo);}else{letobj={github_id:response.id,email:response.email,password:response.login,type:2,avatar:response.avatar_url,name:response.login,location:response.地点,};//注册到数据库letuser=newUser(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上获取的用户信息如下:Final效果:参与文章:https://www.jianshu.com/p/a9c...https://blog.csdn.net/zhuming...2.如何设计第三方授权的用户表登录。第三方授权登录时,第三方用户信息是存储在数据库原有的用户表中,还是新建一张表?答:视具体项目而定。有很多方法可以做到这一点。请看下面。第三方授权登录后,第三方用户信息一般会返回用户唯一标识openid或unionid或id,具体取决于第三方,比如github是id1。通过注册直接保存到数据库中。第一种方式:如果网站没有注册功能,可以直接通过第三方授权登录。授权成功后,可以直接在自己数据库的用户表中注册并保存第三方用户信息。一个典型的例子就是微信的授权登录公众号。第二种:如果网站有注册功能,也可以通过第三方授权登录。授权成功后,也可以直接在自己数据库的user表中注册保存第三用户信息(不过密码是后台自动生成的,用户不知道,只能用第三用户登录)-方授权),此类第三方用户和原注册用户信息在同一个表中,这个情况要看你自己项目的具体情况。笔者的博客站点暂时采用了这种方式。2、添加映射表现实中很多网站都有多种账号登录方式,比如网站注册id登录、手机号登录、QQ登录等。数据库中存在映射关系,QQ、手机号等都映射到网站的注册id。确保无论用什么方式登录,只要查看映射关系,找出哪个id映射到网站注册,就让那个id登录成功。3、创建一张oauth表,一个id列,记录对应用户注册中心的id创建一个oauth表,一个id列,记录对应用户注册中心的id,然后你有多少个第三方登录功能,可以创建多少列,记录第三方登录接口返回的openid;第三方登录时,通过该表记录的openid获取id信息,如果有则通过id读取registry,并记录相关信息与session。如果不存在,则转到用户登录/注册界面,要求用户输入在本站注册的账号进行openid绑定或新注册的账号信息进行绑定。具体代码实践可以参考文章:1.第三方登录用户信息表设计2.浅谈数据库用户表结构设计,第三方登录4.最后附上作者的github博客地址:https://github。对全栈实践感兴趣的朋友可以扫描下方二维码关注我公众号。我会不定期更新有价值的内容,长期运营。关注公众号,回复福利领取免费学习资料。详细福利请点击:Python,Java,Linux,Go,node,vue,react,javaScript