Vue项目怎么接入OAuth2.0

前言

最近公司让我做一下客户端如何接入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

  1. 登录,配置客户端信息并重定向到认证地址,等待用户授权。

    文件地址: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,取得授权码之后认证服务器将会重定向到该地址。

  1. 用户完成授权,取得授权码,我们将携带授权码和配置相关信息向认证服务器申请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或其他存储方式实现,这里就不贴代码了。

项目地址:https://github.com/izekers/OAuthDemo_vue

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容