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

基于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

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

时间: 2024-10-31 08:49:47

通过js和ajax获取token及刷新token示例的相关文章

关于token和refresh token

最近在做公司的认证系统,总结了如下一番心得. 传统的认证方式一般采用cookie/session来实现,这是我们的出发点. 1.为什么选用token而不选用cookie/session?本质上token和cookie/session都是字符串,然而token是自带加密算法和用户信息(比如用户id),:而cookie本身不包含用户信息,它指向的是服务器上用户的 session,而由session保存用户信息.这点差别,决定token可以很容易的跨服务器,只要不同服务器实现相同解密算法即可:而coo

通过XMLHttpRequest和jQuery两种方式实现ajax(即无刷新页面获取数据)

一.XMLHttpRequest实现获取数据 不使用jQuery实现页面不刷新获取内容的方式,我们这里采用XMLHttpRequest原生代码实现:js代码如下: //1.获取a节点,并为其添加Oncilck响应函数document.getElementsByTagName("a")[0].onclick = function(){ //3.创建一个XMLHttpRequest(); var request = new XMLHttpRequest(); //4.准备发送请求的数据ur

通过原生js的ajax或jquery的ajax获取服务器的时间

在实际的业务逻辑中,经常是与时间相关的,而前端能获得的时间有两个:客户端的时间,服务器的时间.客户端时间通过 javascript中的Date对象可以获取,如 Java代码   var dt = new Date(); var tm = dt.getTime(); 那么tm就是客户端的时间,另外也可以通过对应的getFullYear(),getMonth(),getDate()取到对应的年月日等...但这个时间可靠吗?好吧,那取服务器时间吧经常用到的是后台写一个php,jsp,cgi,asp..

angular js 多处获取ajax数据的方法

angular js 多处获取ajax数据的方法 var app=angular.module("cart",[]);app.service("getData",function ($http) { return{ ajax:function () { return $http.get("product.json"); } }}); app.controller("listCtrl",function ($scope,getD

js界面刷新&Django使用Ajax实现页面无刷新评论回复功能

Django使用Ajax实现页面无刷新评论回复功能 http://www.cnblogs.com/mfc-itblog/p/5188900.html js界面刷新 http://www.cnblogs.com/dingdingo/archive/2011/10/26/2225307.html js界面刷新&Django使用Ajax实现页面无刷新评论回复功能

Vue.js&mdash;&mdash;基于$.ajax实现数据的跨域增删查改

概述 之前我们学习了Vue.js的一些基础知识,以及如何开发一个组件,然而那些示例的数据都是local的.在实际的应用中,几乎90%的数据是来源于服务端的,前端和服务端之间的数据交互一般是通过ajax请求来完成的. 说起ajax请求,大家第一时间会想到jQuery.除了拥有强大的DOM处理能力,jQuery提供了较丰富的ajax处理方法,它不仅支持基于XMLHttpRequest的ajax请求,也能处理跨域的JSONP请求. 之前有读者问我,Vue.js能结合其他库一起用吗?答案当然是肯定的,V

JS 操作 AJAX

JS 操作 AJAX Table of Contents API 同步和异步 ajax / text server get post ajax / json server get post ajax / xml server get post 跨域 相关阅读 API onreadystatechange 指定当 readyState 属性改变时的事件处理句柄 readyState 返回当前请求的状态 responseBody 将回应信息正文以 unsigned byte 数组形式返回 respo

原生JS写Ajax的请求函数

原文:http://caibaojian.com/ajax-jsonp.html 一.JS原生ajax ajax:一种请求数据的方式,不需要刷新整个页面:ajax的技术核心是 XMLHttpRequest 对象:ajax 请求过程:创建 XMLHttpRequest 对象.连接服务器.发送请求.接收响应数据: 下面简单封装一个函数,之后稍作解释 1 ajax({ url: "./TestXHR.aspx", //请求地址 2 type: "POST", //请求方式

原生JS实现AJAX、JSONP及DOM加载完成事件

一.JS原生Ajax ajax:一种请求数据的方式,不需要刷新整个页面:ajax的技术核心是 XMLHttpRequest 对象:ajax 请求过程:创建 XMLHttpRequest 对象.连接服务器.发送请求.接收响应数据: 下面简单封装一个函数,之后稍作解释 ajax({ url: "./TestXHR.aspx", //请求地址 type: "POST", //请求方式 data: { name: "super", age: 20 },