前言
最近公司让我做一下客户端如何接入OAuth2.0服务器认证的实例给客户,本身对这块不是很熟悉,上网找了很多资料,这里把我的成果记录一下。这篇文章主要还是讲项目实现,概念的学习感觉还学的不到家,准备整理整理再写。
项目实现主要还是参考了阮一峰老师的《理解OAuth 2.0》吧,大家可以学习这一篇文章,对于OAuth2讲的很详细。
过程实现
下面是接入的过程,实现的授权模式是最常用的授权码(Authorization code)模式的接入方式。
OAuth服务器
既然我们要实现的是接入OAuth2的过程,必不可少的就是OAuth2的服务器,这里我选择用github提供的服务作为一个oAuth2服务器,让github作为OAuth2服务器的步骤如下。
选择setting
选择Developer settings
选择new OAuth App注册并填写信息,可以看到我已经注册两个客户端
这是我填写完成之后的信息
Vue实现
1. 对接环境配置
项目的配置文件放置于路径:src/config/config.js
具体配置:
var config={
//请求授权地址
userAuthorizationUri:"https://github.com/login/oauth/authorize",
//accessToken请求地址
accessTokenUri : "https://github.com/login/oauth/access_token",
//用户信息请求地址
userInfoUri:"https://api.github.com/user",
//登出请求地址
logoutUri:"https://github.com/logout",
//项目地址
localuri :"http://localhost:9999",
//回调地址
redirect_uri : "http://localhost:9999/login",
//案例资源服务器地址
resUri:"http://localhost:8080",
//客户端相关标识,请从认证服务器申请
clientId: "",
client_secret:"",
//申请的权限范围
scope:"user",
//可选参数,客户端的当前状态,可以指定任意值,用于校验,此次案例不做相关认证
state:"",
//一些固定的请求参数
response_type:"token",
grant_type : "authorization_code",
code:"",
}
export default config;
2. 用户登录并获取Access_Token
-
登录,配置客户端信息并重定向到认证地址,等待用户授权。
文件地址:src/util/loginUtils.js login:function (vue) { vue.$config.code = RndNum(4); var authorUrl = vue.$config.userAuthorizationUri; authorUrl = authorUrl + ('?' + vue.$querystring.stringify({ client_id:vue.$config.clientId, response_type:vue.$config.response_type, scope:vue.$config.scope, state:vue.$config.state, redirect_uri:vue.$config.redirect_uri, })) window.location.href = authorUrl; } 其中几个参数的含义: response_type:表示授权类型,必选项,此处的值固定为"code" client_id:表示客户端的ID,必选项 redirect_uri:表示重定向URI,可选项 scope:表示申请的权限范围,可选项 state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
这一步的目的是取得用户的授权并得到授权码,授权码将用于取得Access_Token。
如果配置了参数中的redirect_uri,取得授权码之后认证服务器将会重定向到该地址。
-
用户完成授权,取得授权码,我们将携带授权码和配置相关信息向认证服务器申请Access_Token
文件地址:src/components/ssologin.vue mounted:function () { this.code = this.$route.query.code; this.state = this.$route.query.state; this.getToken(); } 回调取得两个参数的作用: code:表示授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。 state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。 getToken:function(){ this.$token.getTokenFromService(this,this.code,(response)=>{ this.$token.savetoken(response.data); this.$router.push('/user'); },function (error) { alert(error); }); }
文件地址:src/util/token.js getTokenFromService:function (vue,code,callback,error) { vue.$ajax.post(vue.$config.accessTokenUri,{ client_id:vue.$config.clientId, client_secret:vue.$config.client_secret, code:code, redirect_uri:vue.$config.redirect_uri, grant_type:vue.$config.grant_type },{ headers:{"Accept":"application/json"} }) .then(callback) .catch(error); } 相关几个参数的含义: grant_type:表示使用的授权模式,必选项,此处的值固定为"authorization_code"。 code:表示上一步获得的授权码,必选项。 redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。 client_id:表示客户端ID,必选项。
这里获取了Access_Token作为身份凭证,需要我们保存起来,可以保存在cookie中,也可以选择其他方式,在后续访问资源服务器调用资源的时候需要携带Access_Token访问。
跨域问题
在获取Access_Token时我们将会遇到跨域的问题,这里我才用的解决方案是利用proxyTable设置代理,用于解决我们开发环境中跨域问题,而生产环境可以选择nginx等。这里就说一下proxyTable的做法
在config/index.js中的dev添加下面配置
dev:{
proxyTable: {
'/github':{
target:'https://github.com',
changeOrigin:true,
pathRewrite:{
'^/github':'/'
}
}
}
将src/config/config.js文件中的需要跨域的地址
accessTokenUri : "https://github.com/login/oauth/access_token"
改为
accessTokenUri : "/github/login/oauth/access_token"
3. 获取身份信息
获取用户的身份信息是将认证服务器作为资源服务器看待,携带身份凭证Access_Token请求资源,资源服务器将通过认证服务器检测身份凭证的有效性作出相应回复。对于前段我们的做法如下:
getUserInfo:function () {
var tokenInfo = this.$token.loadToken();
this.$ajax({
url:this.$config.userInfoUri+"?"+"access_token="+tokenInfo.access_token,
headers:{"Accept":"application/json"}
})
.then((response) =>{
this.user = response.data;
console.log(this.user);
})
.catch((error) =>{
this.$root.push("/logout")
});
}
4. 注销
通过清除cookie或其他存储方式实现,这里就不贴代码了。
网友评论