成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

第三方登入例子-GitHub授權(quán)登入(node-koa)

Bmob / 834人閱讀

摘要:前言第三方登入太常見(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 Idclient 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_idclient_secretscope。

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

相關(guān)文章

  • 基于node的登入例子node-koa-mongoose)

    摘要:前言這是一個(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ò)...

    lordharrd 評(píng)論0 收藏0
  • MySQL性能調(diào)優(yōu)與架構(gòu)設(shè)計(jì)(三)—— MySQL安全管理

    摘要:處在局域網(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...

    Eminjannn 評(píng)論0 收藏0
  • 單點(diǎn)登入

    摘要:二級(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...

    jeyhan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<