Oauth2.0认证授权
OAuth是一个关于授权(authorization)的开放网络标准,有四种授权方式
授权方式 | 应用场景 | 是否常用 |
---|---|---|
授权码(authorization-code) |
服务一方给另一方授权使用,需要用户确认 | 是 |
隐藏式(implicit) |
授权码模式的简化版,跳转一方服务的sso登录页后,原先返回授权code,改为直接返回token | |
密码式(password) |
普通的系统登录方式,通常用于自我的系统登录,用户输入用户名密码直接登录 | 是 |
客户端凭证(client credentials) |
两服务间调用方式,两系统集成,相互授权访问 | 是 |
一、授权码模式
备注:此处的客户端不是指的浏览器的页面端,是指的异构系统的请求方。
具体流程:
第一步:服务端要配置可接入的客户端,否则任何客户端都可以进行接口调用。以ruoyi-vue-pro为例
- 客户端编号: 客户端的编码,具有唯一性,用于区分不同的客户端
- 客户端密钥: 客户端的秘钥,相当于密码(下面中未使用)
- 应用名: 客户端名称
- 授权类型: 授权模式,这里是授权码模式
- 授权范围: 授权后的权限,比如可以获取用户信息、修改用户基本信息,获取其他要授权的信息
- 可重定向的 URI 地址: 重定向的url,但是客户端请求的时候已经带了,不知道为啥这个地方还要配置下。
第二步:在客户端方为用户提供一个点击跳转的触发按钮,需要跳转至服务端的单点登录授权页
客户端页面代码如下:
<div id="noLoginDiv" style="display: none">
您未登录,点击 <a href="#" onclick="ssoLogin()">跳转 </a> SSO 单点登录
</div>
客户单js代码如下:
/**
* 跳转单点登录
*/
function ssoLogin() {
const clientId = 'yudao-sso-demo-by-code'; // 可以改写成,你的 clientId
const redirectUri = encodeURIComponent('http://127.0.0.1:18080/callback.html'); // 注意,需要使用 encodeURIComponent 编码地址
const responseType = 'code'; // 1)授权码模式,对应 code;2)简化模式,对应 token
window.location.href = 'http://127.0.0.1:1024/sso?client_id=' + clientId
+ '&redirect_uri=' + redirectUri
+ '&response_type=' + responseType;
}
第三步:服务端接收参数,并且返回授权码code
服务端如果没有登录的话,会跳转到服务端系统的登录页,需要用户登录服务端,跳转至sso页面的效果
服务端sso页面代码:
-
页面创建时,获取路径的参数
-
请求服务端获取client的信息,如果client在后台不存在,则就进行阻止
-
服务端的处理逻辑
目前只是通过clientid查询了后台的授权客户端信息及授权范围,判断是否存在此客户端。此处可以追加客户端秘钥的认证。
-
用户点击“授权同意”按钮后,前端js执行授权,并获取授权码code,获取后跳转至客户端的重定向url
-
后端处理请求,并发放授权码,返回客户端的重定向url
第四步:客户端获取授权码,并请求后台获取token
callback页面的代码如下
-
获取请求路劲的code参数
-
请求自己的后端服务,获取token
-
自己的后端服务处理请求
第五步:服务端获取到请求,返回token
controller部分
创建访问令牌,service部分代码
第六步:然后再通过授权范围,调用获取用户的信息,获取用户信息即可,登陆后的效果如下
二、密码模式
第一步:同授权码模式的第一步,增加密码模式的授权方式
第二步:前端login页面如下,输入用户名密码,点击登录
第三步:服务端校验
三、客户端模式
客户端模式与密码模式非常类似,不再赘述。
四、简化的授权码模式(隐藏模式)
实际上在授权码模式获取code时,通过跳转路径返回的不是code,而是token,从代码中也可以看出
五、数据库表设计
评论区