赞
踩
所谓认证就是如何证明你是你自己
的方式,一般来说证明你是你自己的方式就是通过身份证;而互联网中的认证通常用用户名和密码来证明你是你自己。
常用的身份认证的方式一般有:
所谓授权举个例子就是:你在安装手机应用的时候,应用会申请权限,你同意这个权限申请的过程就叫做授权
。同理,在oauth中,被授权方会收获一定的权限。通常使用oauth的厂商有:
授权并不一定需要认证。比如:当你有钥匙的时候,你就可以开门,你并不一定是这个屋子的主人。
在互联网中的oauth
授权通常来说是通过token进行权限的授予的。
OAuth是互联网行业一种标准的授权方式。各个公司根据这一套标准实现自己的OAuth认证和授权流程,而第三方想要接入这个流程,就需要使用OAuth这套方案。
OAuth目前有两个版本:
OAuth第三方认证和授权流程中一般会有几个角色:
另外一种说法说的是客户端和服务端可以合并称为被授权方,如果你做的是个纯客户端的OAuth接入的话,那么你也可以不需要服务端,不过这个接入方式安全性不高。
目前业界的OAuth授权方式有多种,其中最主要的是以下几种:
通过认证码的认证授权方式进行OAuth的接入时,主要流程分别是以下几步:
redirect
到OAuth接入方并附带上client_id
redirect
之后的网站上输入用户名和密码code
。code
之后,拿着client_secret
和code
向OAuth接入方申请获得Token
url:https://github.com/settings/apps
注意:HomePage URL在项目未上线之前填本地项目根路径地址,在项目上线之后填上线之后的域名地址;同理Authorization callback URL
在上线之前填写http://localhost:3000/auth
,在上线之后填写域名+/auth
。
注册成功之后,会出现一个client_id和client_secret,这个两个值非常重要。需要保存在项目文件之中
url: https://github.com/login/oauth/authorize
param:
redirect uri
相同url: https://github.com/login/oauth/access_token
param:
url: https://api.github.com/user
header:
token +access_token
Authorization callback URL
不同时,就会报错。当用户进行完了OAuth流程之后,将token保存于cookie和session中,这样用户就不需要每次切换页面时都去进行一次OAuth认证和授权。
koa框架存储cookie的方式:
server.use(async (ctx, next) => {
ctx.cookies.set('id', id, {
httpOnly: true
});
await next()
})
const session = require('koa-session'); // 给cookie加密,加密之后的密文是jwt server.keys = ['ainuo develop github apps']; const SESSION_CONFIG = { // key为存储的字段名 key: 'jid', // 当没有配置store时,session是以jwt存储在cookie中的 // store: }; // 使用session中间件 server.use(session(SESSION_CONFIG, server)); // 一般来说我们会单独暴露一个接口用于设置session。 router.get('/set/user', async ctx => { // 设置session ctx.session.user = { name: 'ainuo', age: 18 }; ctx.body = 'set session success' });
function getRedisSessionId(sessionId) { return `ssid:${sessionId}` } module.exports = class RedisSessionStore { constructor(client) { this.client = client } // 根据sessionId获取redis中存储的session数据 async get(sessionId) { console.log('get session', sessionId); const id = getRedisSessionId(sessionId); const data = await this.client.get(id); if (!data) { return null } try { return JSON.parse(data); } catch (e) { console.log(e) } } // 存储session数据到redis async set(sessionId, sessionValue, lifetime) { console.log('set session', sessionId); const id = getRedisSessionId(sessionId); if (typeof lifetime === "number") { lifetime = Math.ceil(lifetime / 1000); } try { const sessionStr = JSON.stringify(sessionValue); if (lifetime) { await this.client.setex(id, lifetime, sessionStr) } else { await this.client.set(id, sessionStr) } } catch (e) { console.log(e) } } // 从redis中删除某个session async destroy(sessionId) { console.log('destroy session', sessionId); const id = getRedisSessionId(sessionId); await this.client.del(id) } }
const Redis = require('ioredis'); // 可以传入一些配置 const client = new Redis({}); server.keys = ['ainuo develop github apps']; const SESSION_CONFIG = { key: 'jid', // 当没有配置store时,session是以jwt存储在cookie中的 store: new RedisSessionStore(client), // maxAge: 10 * 1000, }; // 对服务端的session进行加密 server.use(session(SESSION_CONFIG, server)); // 删除session时删除redis数据库中的ssid:xxx的数据 router.get('/del/user', async ctx => { // 设置session ctx.session = null; ctx.body = 'del session success' }); // 设置session时添加session到redis数据库 router.get('/set/user', async ctx => { // 设置session ctx.session.user = { name: 'ainuo', age: 18 }; ctx.body = 'set session success' });
//config,js module.exports = { github: { client_id: '170b16e19a6b3034227d', client_secret: '521f1257450ff42f99cf817eb18de606b9002fd5', request_token_url: 'https://github.com/login/oauth/access_token', auth_url: 'https://github.com/login/oauth/authorize', scope: 'user', user_info_url: 'https://api.github.com/user' } }; // auth.js const axios = require('axios'); const {github} = require('../config'); const {client_id, client_secret, request_token_url} = github; module.exports = function (server) { server.use(async (ctx, next) => { if (ctx.path === '/auth') { const code = ctx.query.code; if (code) { const res = await axios({ method: 'POST', url: request_token_url, data: { client_id, client_secret, code }, headers: { Accept: 'application/json', } }); if (res.status === 200 && !(res.data && res.data.error)) { ctx.session.githubAuth = res.data; const {access_token, token_type} = res.data; const userInfoRes = await axios({ method: 'GET', url: github.user_info_url, headers: { Authorization: `token ${access_token}` } }); ctx.session.userInfo = userInfoRes.data; ctx.redirect('/'); } else { const errorMsg = res.data && res.data.error; ctx.body = `request token failed ${errorMsg}` } } else { ctx.body = 'code not exist'; } } else { await next() } }) }; // server.js // 对服务端的session进行加密 server.use(session(SESSION_CONFIG, server)); // 配置处理github oauth登陆 auth(server);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。