码迷,mamicode.com
首页 > Web开发 > 详细

通过js和ajax获取token及刷新token示例

时间:2018-07-21 17:13:28      阅读:2263      评论:0      收藏:0      [点我收藏+]

标签:定向   send   分享   rem   2.0   auth   localhost   表示   申请   

基于Oauth2.0协议授权码模式

授权码模式工作流程:

(A)浏览器访问该js客户端,js将网页重定向到认证服务器(/oauth/authorize),携带clientid等信息

(B)用户选择是否给予客户端授权(可自动授权)

(C)认证服务器将浏览器重定向到"重定向URI"(redirection URI),同时附上一个授权码

(D)浏览器拿到授权码,附上早先的"重定向URI",向认证服务器申请令牌(/oauth/token)

(E)认证服务器核对了授权码和重定向URI,向客户端发送访问令牌(access token)和更新令牌(refresh token)

 

A步骤中,客户端申请认证的URI,包含以下参数:

  • response_type:表示授权类型,必选项,此处的值固定为"code"
  • client_id:表示客户端的ID,必选项
  • redirect_uri:表示重定向URI,可选项
  • scope:表示申请的权限范围,可选项
  • state:一般随机生成,标识客户端的当前状态,认证服务器会原样返回这个值,

 

通过JS ajax拦截器获取token及刷新token示例,适用于前后端分离项目中前端的授权。

auth.js

const FULL_CHARTER = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopgrstuvwxyz‘;
const oauth_server=‘http://localhost:9000/server‘;
const redirect_uri=‘http://localhost:8002/client-front/‘;
const client_id=‘demo‘;
const client_secret=‘demo‘;
const token_storage = localStorage;//sessionStorage


function ajaxSetup() {
    $.ajaxSetup({
        timeout : 30000,
        beforeSend : function(xhr) {
            if(this.url.endsWith(‘/oauth/token‘)){
                return true;
            }
            if (getAuth() == null){
                fetchToken();
            }
            var auth = getAuth();
            if(auth != null){
                xhr.setRequestHeader("Authorization", auth.token_type + ‘ ‘ + auth.access_token);
            } else {
                return false;
            }
            return true;
        },
        complete : function(xhr, ts) {
            if (xhr.status == 401 && xhr.responseJSON.error ==‘invalid_token‘) {
               refreshToken();
            }
        }
    });
}

function getAuth(){
    let auth = token_storage.getItem(‘auth‘);
    return JSON.parse(auth);
}

function saveAuth(sResponse){
    token_storage.setItem("auth", JSON.stringify(sResponse));
}

function clearAuth(){
    token_storage.removeItem(‘auth‘);
}

function logout(){
    token_storage.removeItem(‘auth‘);
    window.location.href = oauth_server+"/logout?redirect_uri="+redirect_uri;
}

function getCode(){
var state=‘‘;
for (var a=0;a<6;a++){
    state+=FULL_CHARTER[Math.floor(Math.random() * 52)];
}
var url = oauth_server+"/oauth/authorize?client_id="+client_id+"&client_secret="+client_secret+
          "&response_type=code&state="+state+"&redirect_uri="+redirect_uri;
 window.location = url;
 //window.open(url);
}

function fetchToken(){
    let url = window.location.toString();
    if(!url.includes(‘code‘)){
        getCode();
    }
    if(url.includes(‘code‘)) {
      let code=url.substr(url.indexOf(‘code=‘)+5,6);
      let state=url.substr(url.indexOf(‘state=‘)+6,6);

        var data={
        ‘code‘:code,
        ‘state‘:state,
        ‘grant_type‘:‘authorization_code‘,
        ‘redirect_uri‘:redirect_uri
        };
    $.ajax({
       url: oauth_server+"/oauth/token",
       type:"post",
       data:data,
       async: false,
       contentType: ‘application/x-www-form-urlencoded‘,
       beforeSend:function(xhr){
             xhr.setRequestHeader("Authorization", ‘Basic ‘ + Base64.encode(client_id+‘:‘+client_secret));
        },
       success: function (sResponse) {
        saveAuth(sResponse);
        console.log(‘fetch_token ok: ‘ + sResponse.access_token+‘  expires_in:‘+sResponse.expires_in);
        //window.location.href = redirect_uri;
       },
       error:function(a,b,c){
        console.log(a, b, c);
       }
    });
    }
}

function refreshToken(){
    var auth = getAuth();
    var data={
            ‘client_id‘: client_id,
            ‘client_secret‘: client_secret,
            ‘grant_type‘:‘refresh_token‘,
            ‘refresh_token‘:auth.refresh_token
            };
        $.ajax({
           url: oauth_server+"/oauth/token",
           type:"post",
           data:data,
           async: false,
           contentType: ‘application/x-www-form-urlencoded‘,
           success: function (sResponse) {
            saveAuth(sResponse);
            console.log(‘refresh_token ok: ‘ + sResponse.access_token+‘  expires_in:‘+sResponse.expires_in);
           },
           error:function(a,b,c){
            if (a.status==400 && a.responseJSON.error==‘invalid_grant‘){
                console.log(‘refresh token invalid‘);
                clearAuth();
            }
           }
        });
}

function checkToken(){
            $.ajax({
               url: oauth_server+"/oauth/check_token",
               type:"get",
               async: false,
               data: {‘token‘: getAuth().access_token},
               contentType: ‘application/x-www-form-urlencoded‘,
               success: function (sResponse) {
                console.log(‘check_token : ‘ + sResponse);
               },
               error:function(a,b,c){
                console.log(a.responseJSON);
               }
            });
}

function getServerdata(){
    $.get(oauth_server+"/msg", function(data) {
            $("#user").html(data);
          });
}


$(function() {
    ajaxSetup();
});

 

---

其中使用了base64.js,界面如下,点击GET Data按钮将发送/msg请求到授权服务器获取一段文本。

技术分享图片

浏览器所有请求如下:

技术分享图片

首先访问/msg,返回401无权限,然后浏览器转到/oauth/authorize去获取code,然后授权服务器返回302重定向到授权登录页,用户填写用户名密码后post到/login,然后授权服务器重定向到rediret_url,末尾拼接了code,取出code,post发送/oauth/token请求,授权服务器返回token信息如下,并保存在LocalStorage中。

技术分享图片

获取token后/msg请求中携带token信息,bearer为token类型

技术分享图片

由于是跨域请求数据,所以先发送的是OPTIONS请求,需要服务器支持跨域:

技术分享图片

刷新token:

当服务器返回401,并且responseMsg为invalid_token时表示token已失效,post以下信息到/oauth/token,刷新token的失效时间

技术分享图片

checktoken:需要服务器permitAll()该请求

 

登出:

 

授权服务器中的token:

技术分享图片

 

 

end

 

通过js和ajax获取token及刷新token示例

标签:定向   send   分享   rem   2.0   auth   localhost   表示   申请   

原文地址:https://www.cnblogs.com/luangeng/p/9346553.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!