摘要:前言第三方登入太常見了,微信,微博,總有一個你用過。本項目源碼地址第三方登入第三方登入主要基于。授權(quán)回掉處理獲取在第一步授權(quán)請求成功后會給應(yīng)用返回一個回掉。
前言
第三方登入太常見了,微信,微博,QQ...總有一個你用過。當(dāng)然看這篇文章的你,應(yīng)該還用過github登入。這篇分享是在上一篇基于node的登入例子(node-koa-mongoose)的基礎(chǔ)增加了github賬號第三方授權(quán)登入功能,如果有些代碼,這篇中美介紹,你可以先去看下上一篇的分享。
本項目源碼地址:https://github.com/linwalker/...
第三方登入第三方登入主要基于OAuth 2.0。OAuth協(xié)議為用戶資源的授權(quán)提供了一個安全的、開放而又簡易的標(biāo)準(zhǔn)。與以往的授權(quán)方式不同之處是OAUTH的授權(quán)不會使第三方觸及到用戶的帳號信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權(quán),因此OAUTH是安全的 ---- 百度百科
更詳細(xì)的介紹可以看這篇文章理解OAuth 2.0
github 授權(quán)登入 原理過程先來大致了解下第三方通過GitHub賬號授權(quán)登入的過程,具體實現(xiàn)結(jié)合后面代碼講解
1.獲取code
第三方客戶端向`https://github.com/login/oauth/authorize`發(fā)送get請求,帶上`?client_id=XXXXXX`參數(shù),這時會跳轉(zhuǎn)到GitHub登入頁面,授權(quán)后GitHub會向客戶端返回`https://redirect_url?code=XXXXXX`。其中`client_id`和`redirect_url`是第三方事先在GitHub平臺上配置好的。
2.通過code獲取access_token
客戶端處理`https://redirect_url?code=XXXXXX`請求,獲取code值,向`https://github.com/login/oauth/access_token`發(fā)起post請求,請求參數(shù)為`client_di`,`client_secret`和`code`。
3.通過access_token獲取用戶GitHub賬號信息
第二步的請求會返回這樣access_token=d0686dc49a22d64e77402db072b719f510f22421&scope=user&token_type=bearer的內(nèi)容,拿到access_token只需要向https://api.github.com/user?access_token=xxx發(fā)送GET請求,即可獲取到登錄用戶的基本信息,
具體實現(xiàn) GitHub注冊應(yīng)用首先你要有一個GitHub賬號,然后進(jìn)入settings -> OAuth application -> Register a new application。進(jìn)來后你會看到下面這個頁面:
依次填好應(yīng)用名稱,應(yīng)用地址和授權(quán)回掉地址后點擊Register application按鈕,會生成一個client Id和client Secret,用于后面向GitHub發(fā)送請求傳參。
Github授權(quán)請求(獲取code)在頁面中添加GitHub登入跳轉(zhuǎn)按鈕,并在路由中對跳轉(zhuǎn)請求進(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中事先添加配置請求所需參數(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哪些信息,可以填寫多個,以逗號分割,比如:scope=user,public_repo。state參數(shù)非必需,用于防治跨域偽造請求攻擊。
現(xiàn)在可以運(yùn)行一下項目,點擊小黑貓,跳轉(zhuǎn)到授權(quán)登入頁面(沒登入過,要輸入賬號密碼),授權(quán)成功返回回掉地址。
回掉地址中code就是返回的授權(quán)碼,通過授權(quán)碼再去獲取令牌access_token。
授權(quán)回掉處理(獲取access_token)在第一步授權(quán)請求https://github.com/login/oauth/authorize成功后GitHub會給應(yīng)用返回一個回掉http://localhost:3003/github/oauth/callback?code=14de2c737aa02037132d&state=1496989988474。這個回掉地址就是之前在GitHub注冊應(yīng)用時填入的回掉地址,另外還帶了需要的code參數(shù),state就是上一步請求中帶的state參數(shù),原樣返回。
現(xiàn)在我們要對這個回掉請求進(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返回回掉地址時,先拿到請求中的code參數(shù),然后向https://github.com/login/oauth/access_token發(fā)送post請求并帶上client_id,client_secret,code參數(shù),請求成功后會返回帶有access_token的信息。
獲取GitHub賬號信息最后帶上獲取的access_token請求https://api.github.com/user?access_token=xxx,返回的就是之前scope中對應(yīng)的賬號信息。
.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é)用一張圖來總結(jié)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/87026.html
摘要:前言這是一個基于實現(xiàn)的一個簡單登入例子,對于剛上手想進(jìn)一步了解,前端頁面如何請求到服務(wù)層路由處理數(shù)據(jù)庫操作返回結(jié)果到頁面這整個過程的同學(xué)比較有用。我們來看下登入請求處理。操作演示演示用戶名不存在,密碼錯誤及成功登入。 前言 這是一個基于node實現(xiàn)的一個簡單登入例子,對于剛上手node想進(jìn)一步了解,前端頁面如何請求到服務(wù)層 -> 路由處理 -> 數(shù)據(jù)庫操作 -> 返回結(jié)果到頁面這整個過...
摘要:處在局域網(wǎng)之內(nèi)的,由于有局域網(wǎng)出入口的網(wǎng)絡(luò)設(shè)備的基本保護(hù),相對于暴露在廣域網(wǎng)中要安全不少,主要威脅對象基本控制在了可以接入局域網(wǎng)的內(nèi)部潛在威脅者,和極少數(shù)能夠突破最外圍防線局域網(wǎng)出入口的安全設(shè)備的入侵者。 前言 對于任何一個企業(yè)來說,其數(shù)據(jù)庫系統(tǒng)中所保存數(shù)據(jù)的安全性無疑是非常重要的,尤其是公司的有些商業(yè)數(shù)據(jù),可能數(shù)據(jù)就是公司的根本。 失去了數(shù)據(jù),可能就失去了一切 本章將針對mysql...
閱讀 1261·2021-09-02 13:36
閱讀 2714·2019-08-30 15:44
閱讀 2972·2019-08-29 15:04
閱讀 3193·2019-08-26 13:40
閱讀 3643·2019-08-26 13:37
閱讀 1172·2019-08-26 12:22
閱讀 1003·2019-08-26 11:36
閱讀 1214·2019-08-26 10:41