上一篇文章总结了Authorization Server, 这一篇总结一下Client端的实现。先看一下之前那幅图。
授权请求是由客户端触发的,客户端可以有很多种形式:MVC后端系统,前后端分离的SPA,移动端的Native App。这里以SPA和授权码模式作为例子。主要使用oidc-client库来实现与Authorization Server的对接。在SPA中添加依赖后,我们就可以来编写认证模块了。主要是两个过程:发起OAuth授权和token交换(根据code获取id_token,access_token)。
发起OAuth授权
import Oidc from 'oidc-client'; var config = { authority: "https://localhost:5001/",//Authorization server地址 client_id: "js", //Client Id,需要在Authorization Server配置好
redirect_uri: "http://localhost:3000/callback.html", //redirect url, 用于接受授权码,然后通过token交换获取id_token和access_token
response_type: "code", //授权方式,一般SPA应用首选授权码模式
scope:"openid api email profile", //请求授权的scope,包含需要获取的用户信息以及想访问的资源的权限。
};
var mgr = new Oidc.UserManager(config);// UserManager类是oidc-client库的主要接口,几乎所有接口都通过该对象进行调用。(详见api文档)
//login函数,供外部调用
function login(){
mgr.signinRedirect();//触发OAuth授权请求
}
token交换
token交换的过程主要是实现一个callback的页面,Authorization Server通过该页面以Query string的形式传递授权码到客户端。在该页面中通过调用oidc-client的signinRedirectCallback函数进行token交换。
<script src="oidc-client.js"></script> <script> new Oidc.UserManager({response_mode:"query"}).signinRedirectCallback().then(function() { window.location = "index.html"; }).catch(function(e) { console.error(e); });
</script>
这两个Api调用的背后是OpenID协议的实现,具体流程如下:
这两个过程结束之后,access_token和id_token会被存储在浏览器的session storage中。
到这里,OAuth授权的token获取就成功了。接下来我么可以通过api getUser()来获取存储在session storage中的token信息来调用后台rest api了。
function getUser(){ new UserManager().getUser() .then(function (user) { if (user) { var url = `https://localhost:44342/api/user; let options = { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${user.access_token}`,//设置Athorization头供rest api认证。 }, }; return fetch(url, options); }).then(resp=>{ if(resp.ok){ return resp.json(); } }.then(user=>{
console.log(user);
})
.catch(error=>{
console.log(error);
}); }
总结:
对于SPA应用,集成OAuth协议主要是对oidc-client库的使用。该库对OAuth,OpenID协议的集成进行了高度的封装。很容易使用。