更好的阅读体验请访问:docs.authing.cn/authing/qui…javascript
若是你不了解用户池、单点登陆和认证受权,建议先阅读基础概念。html
基本的 HTML 和 CSS 知识java
中级 JavaScript 技能git
你喜欢的文本编辑器github
能够在本地运行的 Web 服务器(好比:npm install http-server -g
)web
若是你尚未帐号,请点击这里注册 Authing 帐号,注册完成后请进入控制台并建立一个用户池。算法
第三方登陆 -> OIDC 应用选项卡,点击蓝色的「建立 OIDC 应用」按钮。npm
参数解释json
认证地址,一个 authing.cn 的二级域名,用户将在此网址进行登陆。浏览器
回调 URL,OIDC 登陆成功后,回调到开发者本身业务的地址。本教程为演示,填写的地址是 http://localhost:8080,实际场景下要填写本身的业务地址。
在应用列表中点击刚建立好的应用,记录下 AppID,二级域名,供之后使用。
本教程只是为了演示,所以咱们没选择高级框架,这可让咱们专一于 Authing 自己。
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Authing SSO Example</title> </head> <body></body></html>复制代码
增长三个按钮控件到 body 中,目的是为了演示如何使用 SDK 管理单点登陆状态。
<button id="btn-login">login</button><button id="btn-track-session">trackSession</button><button id="btn-logout">logout</button>复制代码
从 CDN 加载 AuthingSSO 的 SDK。填入你的 OIDC 应用 ID 和 域名,进行初始化。
<script src="https://cdn.jsdelivr.net/npm/@authing/sso/dist/AuthingSSO.umd.min.js"></script><script> let auth = new AuthingSSO({ appId: "YOUR_OIDC_APP_ID", appType: "oidc", appDomain: "OIDC_APP_DOMAIN.authing.cn" });</script>复制代码
达到的效果是:
点击 login 按钮,浏览器会跳转到 OIDC 登陆页面,与用户完成身份确认。
点击 trackSession 按钮,会显示当前登陆状态。
点击 logout 按钮,进行单点登出。
let login = document.getElementById("btn-login");let trackSession = document.getElementById("btn-track-session");let logout = document.getElementById("btn-logout");login.onclick = function() { auth.login();};trackSession.onclick = async function() { let res = await auth.trackSession(); alert(JSON.stringify(res));};logout.onclick = async function() { let res = await auth.logout(); alert(JSON.stringify(res));};复制代码
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Authing SSO Example</title> </head> <body> <button id="btn-login">login</button> <button id="btn-track-session">trackSession</button> <button id="btn-logout">logout</button> <script src="https://cdn.jsdelivr.net/npm/@authing/sso/dist/AuthingSSO.umd.min.js"></script> <script> let auth = new AuthingSSO({ appId: "YOUR_OIDC_APP_ID", appType: "oidc", appDomain: "OIDC_APP_DOMAIN.authing.cn" }); let login = document.getElementById("btn-login"); let trackSession = document.getElementById("btn-track-session"); let logout = document.getElementById("btn-logout"); login.onclick = function() { auth.login(); }; trackSession.onclick = async function() { let res = await auth.trackSession(); alert(JSON.stringify(res)); }; logout.onclick = async function() { let res = await auth.logout(); alert(JSON.stringify(res)); }; </script> </body></html>复制代码
示例代码可从 Github 上找到,建议将 Github 上的代码下载运行。
在终端中运行如下命令
$ git clone https://github.com/Authing/authing-sso-demo
$ cd authing-sso-demo
$ npm install -g http-server
$ http-server复制代码
以后在浏览器访问 http://localhost:8080。
若是本地 8080 端口已被占用,应用可能会运行在 808一、8082 等后续端口。
最初,咱们没有登陆,所以,点击 trackSession 按钮获取到的登陆状态为空。
如今咱们点击 login 按钮,会跳转到 OIDC 应用的用户认证页面,输入用户名密码进行登陆。
浏览器被重定向到咱们以前设置的回调连接,记下 code 参数,用于后面换取用户信息。
点击 trackSession 按钮,此时可以获取到该用户的登陆状态,包括用户 ID,应用 ID,应用类型。
点击 logout 按钮,输出单点登出成功。
此时咱们再点击 trackSession 按钮,可见登陆状态为空,说明用户已经单点登出了。
向如下地址发送 POST 请求:
POST https://OIDC_APP_DOMAIN.authing.cn/oauth/oidc/token复制代码
body 参数
参数名 |
意义 |
client_id |
OIDC 应用的 app_id |
redirect_uri |
在控制台配置的 OIDC 回调 url 其中的一个值 |
scope |
须要请求的权限,若是须要获取 email 和手机号须要有 phone email,若是须要 refresh_token 须要包含 offline_access 参考 scope 表格 |
response_type |
OIDC 模式,能够为 code, id_token, id_token token, code id_token, code token, code id_token token 参考 OIDC 规范 |
prompt |
能够为 none,login,consent 或 select_account,指定 AP 与 End-User 的交互方式,如需 refresh_token,必须为 consent 参考 OIDC 规范 |
state |
一个随机字符串,用于防范 CSRF 攻击,若是 response 中的 state 值和发送请求以前设置的 state 值不一样,说明受到攻击 |
nonce |
一个随机字符串,用于防范 Replay 攻击 |
返回示例
{ "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InIxTGtiQm8zOTI1UmIyWkZGckt5VTNNVmV4OVQyODE3S3gwdmJpNmlfS2MifQ.eyJqdGkiOiJ4R01uczd5cmNFckxiakNRVW9US1MiLCJzdWIiOiI1YzlmNzVjN2NjZjg3YjA1YTkyMWU5YjAiLCJpc3MiOiJodHRwczovL2F1dGhpbmcuY24iLCJpYXQiOjE1NTQ1Mzc4NjksImV4cCI6MTU1NDU0MTQ2OSwic2NvcGUiOiJvcGVuaWQgcHJvZmlsZSBvZmZsaW5lX2FjY2VzcyBwaG9uZSBlbWFpbCIsImF1ZCI6IjVjYTc2NWUzOTMxOTRkNTg5MWRiMTkyNyJ9.wX05OAgYuXeYM7zCxhrkvTO_taqxrCTG_L2ImDmQjMml6E3GXjYA9EFK0NfWquUI2mdSMAqohX-ndffN0fa5cChdcMJEm3XS9tt6-_zzhoOojK-q9MHF7huZg4O1587xhSofxs-KS7BeYxEHKn_10tAkjEIo9QtYUE7zD7JXwGUsvfMMjOqEVW6KuY3ZOmIq_ncKlB4jvbdrduxy1pbky_kvzHWlE9El_N5qveQXyuvNZVMSIEpw8_y5iSxPxKfrVwGY7hBaF40Oph-d2PO7AzKvxEVMamzLvMGBMaRAP_WttBPAUSqTU5uMXwMafryhGdIcQVsDPcGNgMX6E1jzLA", "expires_in": 3600, "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6InIxTGtiQm8zOTI1UmIyWkZGckt5VTNNVmV4OVQyODE3S3gwdmJpNmlfS2MifQ.eyJzdWIiOiI1YzlmNzVjN2NjZjg3YjA1YTkyMWU5YjAiLCJub25jZSI6IjIyMTIxIiwiYXRfaGFzaCI6Ik5kbW9iZVBZOEFFaWQ2T216MzIyOXciLCJzaWQiOiI1ODM2NzllNC1lYWM5LTRjNDEtOGQxMS1jZWFkMmE5OWQzZWIiLCJhdWQiOiI1Y2E3NjVlMzkzMTk0ZDU4OTFkYjE5MjciLCJleHAiOjE1NTQ1NDE0NjksImlhdCI6MTU1NDUzNzg2OSwiaXNzIjoiaHR0cHM6Ly9hdXRoaW5nLmNuIn0.IQi5FRHO756e_eAmdAs3OnFMU7QuP-XtrbwCZC1gJntevYJTltEg1CLkG7eVhdi_g5MJV1c0pNZ_xHmwS0R-E4lAXcc1QveYKptnMroKpBWs5mXwoOiqbrjKEmLMaPgRzCOdLiSdoZuQNw_z-gVhFiMNxI055TyFJdXTNtExt1O3KmwqanPNUi6XyW43bUl29v_kAvKgiOB28f3I0fB4EsiZjxp1uxHQBaDeBMSPaRVWQJcIjAJ9JLgkaDt1j7HZ2a1daWZ4HPzifDuDfi6_Ob1ZL40tWEC7xdxHlCEWJ4pUIsDjvScdQsez9aV_xMwumw3X4tgUIxFOCNVEvr73Fg", "refresh_token": "WPsGJbvpBjqXz6IJIr1UHKyrdVF", "scope": "openid profile offline_access phone email", "token_type": "Bearer"}复制代码
OIDC 默认使用 OIDC 应用的 secret 对 token 进行验证(也就是在建立应用时默认选择 HS256 算法)。 若是你使用 javascript 那么可使用 jsonwebtoken 进行验证:
const jwt = require('jsonwebtoken');复制代码
let decoded = jwt.verify(token, <appSecret>);复制代码
若是是其余语言,那么你在服务端须要用 app_secret 做为 HS256 签名参数来计算签名和 JWT 中的签名进行对比,伪代码以下:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), "1133fd20c14e4cc29b6ecb71fb8eb952"// app_secret)复制代码
若是是 RS256 等非对称加密算法,须要使用公钥验证签名。Authing 将使用私钥进行签名,请使用 Authing 的公钥来验证签名:
-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxRijj2seoesv5K0Z+ymRK7DSDPxdsM2sGQD2ZVhLjLsxZWJtXUXh7ERdUU6OT3BqYZZf7CLIhN6yyNtTOgfgpLG9HVJd7ZSKzuy2dS7mo8jD8YRtptAJmNFqw6z8tQp5MNG1ZHqp9isKqJmx/CFYkRdXBmjjj8PMVSP757pkC3jCq7fsi0drSSg4lIxrSsGzL0++Ra9Du71Qe/ODQKU0brxaI1OKILtfcVPTHTaheV+0dw4eYkSDtyaLBG3jqsQbdncNg8PCEWchNzdO6aajUq4wbOzy/Ctp399mz0SGKfuC5S8gqAFABFT3DH3UD21ZztQZwFEV2AlvF+bcGEstcwIDAQAB-----END PUBLIC KEY-----复制代码
开发者在本身的服务中可使用 access_token 换取用户信息。根据 scope 的不一样,这里的返回信息也会有所不一样,字段符合 OIDC 规范,字段解释请参考用户信息字段含义。 请求连接:
GET https://users.authing.cn/oauth/oidc/user/userinfo?access_token=<access_token>复制代码
返回示例:
{ "sub": "<用户在 Authing 的惟一标识>", "nickname": "Authing", "name": "张三", "locale": "en-US"}复制代码
更多字段解释请参考用户信息字段含义。