摘要:前言第三方登入太常見(jiàn)了,微信,微博,總有一個(gè)你用過(guò)。本項(xiàng)目源碼地址第三方登入第三方登入主要基于。授權(quán)回掉處理獲取在第一步授權(quán)請(qǐng)求成功后會(huì)給應(yīng)用返回一個(gè)回掉。
前言
第三方登入太常見(jiàn)了,微信,微博,QQ...總有一個(gè)你用過(guò)。當(dāng)然看這篇文章的你,應(yīng)該還用過(guò)github登入。這篇分享是在上一篇基于node的登入例子(node-koa-mongoose)的基礎(chǔ)增加了github賬號(hào)第三方授權(quán)登入功能,如果有些代碼,這篇中美介紹,你可以先去看下上一篇的分享。
本項(xiàng)目源碼地址:https://github.com/linwalker/...
第三方登入第三方登入主要基于OAuth 2.0。OAuth協(xié)議為用戶資源的授權(quán)提供了一個(gè)安全的、開(kāi)放而又簡(jiǎn)易的標(biāo)準(zhǔn)。與以往的授權(quán)方式不同之處是OAUTH的授權(quán)不會(huì)使第三方觸及到用戶的帳號(hào)信息(如用戶名與密碼),即第三方無(wú)需使用用戶的用戶名與密碼就可以申請(qǐng)獲得該用戶資源的授權(quán),因此OAUTH是安全的 ---- 百度百科
更詳細(xì)的介紹可以看這篇文章理解OAuth 2.0
github 授權(quán)登入 原理過(guò)程先來(lái)大致了解下第三方通過(guò)GitHub賬號(hào)授權(quán)登入的過(guò)程,具體實(shí)現(xiàn)結(jié)合后面代碼講解
1.獲取code
第三方客戶端向`https://github.com/login/oauth/authorize`發(fā)送get請(qǐng)求,帶上`?client_id=XXXXXX`參數(shù),這時(shí)會(huì)跳轉(zhuǎn)到GitHub登入頁(yè)面,授權(quán)后GitHub會(huì)向客戶端返回`https://redirect_url?code=XXXXXX`。其中`client_id`和`redirect_url`是第三方事先在GitHub平臺(tái)上配置好的。
2.通過(guò)code獲取access_token
客戶端處理`https://redirect_url?code=XXXXXX`請(qǐng)求,獲取code值,向`https://github.com/login/oauth/access_token`發(fā)起post請(qǐng)求,請(qǐng)求參數(shù)為`client_di`,`client_secret`和`code`。
3.通過(guò)access_token獲取用戶GitHub賬號(hào)信息
第二步的請(qǐng)求會(huì)返回這樣access_token=d0686dc49a22d64e77402db072b719f510f22421&scope=user&token_type=bearer的內(nèi)容,拿到access_token只需要向https://api.github.com/user?access_token=xxx發(fā)送GET請(qǐng)求,即可獲取到登錄用戶的基本信息,
具體實(shí)現(xiàn) GitHub注冊(cè)應(yīng)用首先你要有一個(gè)GitHub賬號(hào),然后進(jìn)入settings -> OAuth application -> Register a new application。進(jìn)來(lái)后你會(huì)看到下面這個(gè)頁(yè)面:
依次填好應(yīng)用名稱,應(yīng)用地址和授權(quán)回掉地址后點(diǎn)擊Register application按鈕,會(huì)生成一個(gè)client Id和client Secret,用于后面向GitHub發(fā)送請(qǐng)求傳參。
Github授權(quán)請(qǐng)求(獲取code)在頁(yè)面中添加GitHub登入跳轉(zhuǎn)按鈕,并在路由中對(duì)跳轉(zhuǎn)請(qǐng)求進(jìn)行轉(zhuǎn)發(fā)處理:
//在node-login/components/LoginTab.js
添加跳轉(zhuǎn)按鈕后,增加相應(yīng)路由處理,路由入口中添加/github路徑處理
//在node-login/routes/index.js const github = require("./github"); router.use("/github", github.routes(), github.allowedMethods());
最后是具體的路由處理
//在node-login/routes/github.js const config = require("../config"); const router = require("koa-router")(); const fetch = require("node-fetch"); const routers = router .get("/login", async (ctx) => { var dataStr = (new Date()).valueOf(); //重定向到認(rèn)證接口,并配置參數(shù) var path = "https://github.com/login/oauth/authorize"; path += "?client_id=" + config.client_id; path += "&scope=" + config.scope; path += "&state=" + dataStr; //轉(zhuǎn)發(fā)到授權(quán)服務(wù)器 ctx.redirect(path); }) module.exports = routers;
在config中事先添加配置請(qǐng)求所需參數(shù)client_id,client_secret和scope。
module.exports = { "database": "mongodb://localhost:27017/node-login", "client_id": "83b21756e93d6ce27075", "client_secret": "d87c4163ece5695a9ded1e8bf2701c5ee2651f28", "scope": ["user"], };
其中scope參數(shù)可選。就是你期待你的應(yīng)用需要調(diào)用Github哪些信息,可以填寫(xiě)多個(gè),以逗號(hào)分割,比如:scope=user,public_repo。state參數(shù)非必需,用于防治跨域偽造請(qǐng)求攻擊。
現(xiàn)在可以運(yùn)行一下項(xiàng)目,點(diǎn)擊小黑貓,跳轉(zhuǎn)到授權(quán)登入頁(yè)面(沒(méi)登入過(guò),要輸入賬號(hào)密碼),授權(quán)成功返回回掉地址。
回掉地址中code就是返回的授權(quán)碼,通過(guò)授權(quán)碼再去獲取令牌access_token。
授權(quán)回掉處理(獲取access_token)在第一步授權(quán)請(qǐng)求https://github.com/login/oauth/authorize成功后GitHub會(huì)給應(yīng)用返回一個(gè)回掉http://localhost:3003/github/oauth/callback?code=14de2c737aa02037132d&state=1496989988474。這個(gè)回掉地址就是之前在GitHub注冊(cè)應(yīng)用時(shí)填入的回掉地址,另外還帶了需要的code參數(shù),state就是上一步請(qǐng)求中帶的state參數(shù),原樣返回。
現(xiàn)在我們要對(duì)這個(gè)回掉請(qǐng)求進(jìn)行處理:
//node-login/routes/github.js const config = require("../config"); const router = require("koa-router")(); const fetch = require("node-fetch"); const routers = router .get("/login", async (ctx) => { ... }) .get("/oauth/callback", async (ctx) => { const code = ctx.query.code; let path = "https://github.com/login/oauth/access_token"; const params = { client_id: config.client_id, client_secret: config.client_secret, code: code } console.log(code); await fetch(path, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(params) }) .then(res => { return res.text(); }) .then(body => { ctx.body = body; }) .catch(e => { console.log(e); }) }) module.exports = routers;
GitHub返回回掉地址時(shí),先拿到請(qǐng)求中的code參數(shù),然后向https://github.com/login/oauth/access_token發(fā)送post請(qǐng)求并帶上client_id,client_secret,code參數(shù),請(qǐng)求成功后會(huì)返回帶有access_token的信息。
獲取GitHub賬號(hào)信息最后帶上獲取的access_token請(qǐng)求https://api.github.com/user?access_token=xxx,返回的就是之前scope中對(duì)應(yīng)的賬號(hào)信息。
.get("/oauth/callback", async (ctx) => { const code = ctx.query.code; let path = "https://github.com/login/oauth/access_token"; const params = { client_id: config.client_id, client_secret: config.client_secret, code: code } console.log(code); await fetch(path, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(params) }) .then(res => { return res.text(); }) .then(body => { const args = body.split("&"); let arg = args[0].split("="); const access_token = arg[1]; console.log(body); console.log(access_token); return access_token; }) .then(async(token) => { const url = " https://api.github.com/user?access_token=" + token; console.log(url); await fetch(url) .then(res => { return res.json(); }) .then(res => { console.log(res); ctx.body = res; }) }) .catch(e => { console.log(e); }) })
返回的用戶信息如下:
總結(jié)用一張圖來(lái)總結(jié)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/87026.html
摘要:前言這是一個(gè)基于實(shí)現(xiàn)的一個(gè)簡(jiǎn)單登入例子,對(duì)于剛上手想進(jìn)一步了解,前端頁(yè)面如何請(qǐng)求到服務(wù)層路由處理數(shù)據(jù)庫(kù)操作返回結(jié)果到頁(yè)面這整個(gè)過(guò)程的同學(xué)比較有用。我們來(lái)看下登入請(qǐng)求處理。操作演示演示用戶名不存在,密碼錯(cuò)誤及成功登入。 前言 這是一個(gè)基于node實(shí)現(xiàn)的一個(gè)簡(jiǎn)單登入例子,對(duì)于剛上手node想進(jìn)一步了解,前端頁(yè)面如何請(qǐng)求到服務(wù)層 -> 路由處理 -> 數(shù)據(jù)庫(kù)操作 -> 返回結(jié)果到頁(yè)面這整個(gè)過(guò)...
摘要:處在局域網(wǎng)之內(nèi)的,由于有局域網(wǎng)出入口的網(wǎng)絡(luò)設(shè)備的基本保護(hù),相對(duì)于暴露在廣域網(wǎng)中要安全不少,主要威脅對(duì)象基本控制在了可以接入局域網(wǎng)的內(nèi)部潛在威脅者,和極少數(shù)能夠突破最外圍防線局域網(wǎng)出入口的安全設(shè)備的入侵者。 前言 對(duì)于任何一個(gè)企業(yè)來(lái)說(shuō),其數(shù)據(jù)庫(kù)系統(tǒng)中所保存數(shù)據(jù)的安全性無(wú)疑是非常重要的,尤其是公司的有些商業(yè)數(shù)據(jù),可能數(shù)據(jù)就是公司的根本。 失去了數(shù)據(jù),可能就失去了一切 本章將針對(duì)mysql...
摘要:二級(jí)域名單點(diǎn)登入實(shí)現(xiàn)結(jié)構(gòu)結(jié)構(gòu)如果中有些屬性經(jīng)常變用有需求同一賬號(hào)只能一處登入令牌,唯一登入驗(yàn)證登入頁(yè)面登入校驗(yàn)賬密,存這個(gè)用,頂級(jí)域名單點(diǎn)登入頂級(jí)域名的登入與二級(jí)域名的單點(diǎn)登入不同的是不能共享。 二級(jí)域名-單點(diǎn)登入 showImg(https://segmentfault.com/img/remote/1460000008606273?w=1125&h=1021); 實(shí)現(xiàn) cooki...
閱讀 1281·2021-09-02 13:36
閱讀 2735·2019-08-30 15:44
閱讀 2990·2019-08-29 15:04
閱讀 3208·2019-08-26 13:40
閱讀 3657·2019-08-26 13:37
閱讀 1196·2019-08-26 12:22
閱讀 1034·2019-08-26 11:36
閱讀 1230·2019-08-26 10:41