OAuth 授权认证(第三方登录)

978 阅读4分钟

文章已同步至【个人博客】,欢迎访问【我的主页】😃
文章地址:blog.fanjunyang.zone/archives/oa…

本章以第三方应用(GitHub)为例,来模拟实现获取第三方应用的权限用户资料

基本的认证流程:

执行步骤从上到下

首先我们需要新建一个文件,并安装依赖来写我们的代码:

接着我们需要在index.html中生成一个模板,并引入需要使用到的script标签:

当然,如果在项目中的话,肯定不这样使用,在项目中都是前后端分离的,使用Vue模板进行书写,这里只是为了书写测试更加方便而已

index.html代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <!-- 引入vue -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <!-- 引入axios -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <title>Index</title>
</head>

<body>
    <div id="app">
        <h1>使用github登录</h1>
        <!-- 定义一个链接,当点击的时候,可以调用后台的接口 -->
        <a href="/github/login">login with github</a>
    </div>
</body>
<script>
    new Vue({
        el: "#app"
    })
</script>

</html>

接着我们需要在index.js文件中引入要使用到的依赖,并对index.html文件进行托管:

const koa = require('koa')
const router = require('koa-router')()
const static = require('koa-static')
const axios = require('axios')
const querystring = require('querystring')

const app = new koa()

// 用来托管静态资源,此处托管的是 index.html
app.use(static(__dirname + '/'))

//配置路由
app.use(router.routes()); // 启动路由
app.use(router.allowedMethods());

//监听3000端口
app.listen(3000)

然后进入文件夹下,使用nodemon index.js把服务跑起来

测试:

然后我们需要进入到网址:github.com/settings/ap… 来创建一个应用

如下:

然后会生成一个应用,并生成一个Client ID Client Secret,这两个东西非常重要,我们要在我们后端定义一个变量来把他们存放起来

index.js文件新增代码:

const config = {
    client_id: '99425ffcd07341565215',
    client_secret: '4f4c405d2002f5ca33cf6980febb080de74ca0f8'
}

接着当我们点击网页上面的超链接的时候,我们需要跳转到GitHub的认证页面https://github.com/login/oauth/authorize并且需要带上client_id

然后我们需要认证,自己直接填入账号密码,然后会让你填写code,会把code发给你的邮箱(注册github的邮箱),只需填上认证一下就OK了(这里我已经认证过了)

接着当我们认证成功的时候,就会返回到上面你填写的那个页面,我填的是(http://127.0.0.1:3000/github/callback)

接下来在index.js中写代码进行测试:

const koa = require('koa')
const router = require('koa-router')()
const static = require('koa-static')
const axios = require('axios')
const querystring = require('querystring')

const app = new koa()

// 用来托管静态资源,此处托管的是 index.html
app.use(static(__dirname + '/'))

const config = {
    client_id: '99425ffcd07341565215',
    client_secret: '4f4c405d2002f5ca33cf6980febb080de74ca0f8'
}

router.get('/github/login', ctx => {
    //需要重定向到github的认证页面,需要带上client_id
    let path = 'https://github.com/login/oauth/authorize?client_id=' + config.client_id
    ctx.redirect(path)

})

router.get('/github/callback', (ctx) => {
    //打印一句话进行测试
    console.log('callback...');
})

app.use(router.routes()); // 启动路由
app.use(router.allowedMethods());

app.listen(3000)

测试:

然后我们需要在/github/callback接口中来获得code,用code申请令牌,然后解析令牌,用令牌获取用户信息

下面使用的网址都是固定的网址,只是每个人所带的参数不一样

修改index.js代码如下:

const koa = require('koa')
const router = require('koa-router')()
const static = require('koa-static')
const axios = require('axios')
const querystring = require('querystring')

const app = new koa()

// 用来托管静态资源,此处托管的是 index.html
app.use(static(__dirname + '/'))

const config = {
    client_id: '99425ffcd07341565215',
    client_secret: '4f4c405d2002f5ca33cf6980febb080de74ca0f8'
}

router.get('/github/login', ctx => {
    //需要重定向到github的认证页面,需要带上client_id
    let path = 'https://github.com/login/oauth/authorize?client_id=' + config.client_id
    ctx.redirect(path)

})

//当我们的github认证成功的时候,会调用这个接口
router.get('/github/callback', async (ctx) => {
    //打印一句话进行测试
    // console.log('callback...');

    // 在认证成功的时候,我们会收到code
    const code = ctx.query.code
    // console.log(code);  //072a58edf792558ae6a9

    //接下来我们需要申请令牌,需要使用到三个参数
    const params = {
        client_id: config.client_id,    //上面定义的config中的参数
        client_secret: config.client_secret,    //上面定义的config中的参数
        code: code  //认证成功时,返回的code
    }
    //获取令牌
    let res = await axios.post("https://github.com/login/oauth/access_token", params)
    // console.log(res.data)

        
    //利用querystring把令牌进行解析,然后获取access_token
    const access_token = querystring.parse(res.data).access_token;
    // console.log(access_token) 

    //有了access_token后,就可以拿到用户信息了,需要带上access_token,当然在项目中,会在请求拦截那里带上这个token
    res = await axios.get("https://api.github.com/user?access_token=" + access_token)
    // console.log(res.data) // 得到一堆的用户信息

    //输出用户部分信息
    ctx.body = `
        <h1>hello ${res.data.login}</h1>
        <img src=${res.data.avatar_url} />
    `

})

app.use(router.routes()); // 启动路由
app.use(router.allowedMethods());

app.listen(3000)

测试:

至此,就可以获取到用户信息,然后就可以使用用户信息。


@_@