Skip to main content

Javascript

集成 Authok

安装依赖

# npm
npm i --save @authok/authok-spa-js
# yarn
yarn add @authok/authok-spa-js

Authok SPA SDK 安装后, 在应用入口导入:

import createAuthokClient from '@authok/authok-spa-js';

通过 CDN 引入

<script src="https://cdn.authok.cn/js/authok-spa-js/1.19.7/authok-spa-js.production.js"></script>

创建 JavaScript 应用

创建基础 HTML页面

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>SPA SDK 示范</title>
<link rel="stylesheet" type="text/css" href="/css/main.css" />
</head>

<body>
<h2>SPA 认证示范</h2>
<p>欢迎!</p>
<button id="btn-login" disabled="true" onclick="login()">登录</button>
<button id="btn-logout" disabled="true" onclick="logout()">退登</button>
</body>
</html>

应用目录结构

.
├── index.html
├── auth_config.json
└── public
├── css
│ └── main.css
└── js
└── app.js

引入SDK

body 底部引入.

index.html
<body>
<!-- other HTML -->
<!-- add the lines below existing code -->
<script src="https://cdn.authok.cn/js/authok-spa-js/1.19.7/authok-spa-js.production.js"></script>
<script src="js/app.js"></script>
</body>

配置

auth_config.json
{
"domain": "YOUR_DOMAIN",
"clientId": "YOUR_CLIENT_ID"
}

创建Server

npm init -y

安装依赖

npm i express

安装 nodemon 以便修改代码后马上热更新:

npm i -D nodemon

打开 package.json 文件进行修改:

package.json
{
// ...
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js"
},
// ...
}
  • npm start 会正常启动应用
  • npm run dev会使用 nodemon启动应用, 此时会监听文件变化.

创建 server.js

server.js
const express = require("express");
const { join } = require("path");
const app = express();

// Serve static assets from the /public folder
app.use(express.static(join(__dirname, "public")));

// Endpoint to serve the configuration file
app.get("/auth_config.json", (req, res) => {
res.sendFile(join(__dirname, "auth_config.json"));
});

// Serve the index page for all other requests
app.get("/*", (_, res) => {
res.sendFile(join(__dirname, "index.html"));
});

// Listen on port 3000
app.listen(3000, () => console.log("Application running on port 3000"));

初始化SDK

public/js/app.js
let authok = null;

const fetchAuthConfig = () => fetch("/auth_config.json");

// ..

const configureClient = async () => {
const response = await fetchAuthConfig();
const config = await response.json();

authok = await createAuthokClient({
domain: config.domain,
client_id: config.clientId
});
};

添加一个 window.onload 回调用于初始化应用:

public/js/app.js
// ..
window.onload = async () => {
await configureClient();

// 更新UI状态
updateUI();
}

const updateUI = async () => {
const isAuthenticated = await authok.isAuthenticated();

document.getElementById("btn-logout").disabled = !isAuthenticated;
document.getElementById("btn-login").disabled = isAuthenticated;
};

登录

public/js/app.js
// ..
const login = async () => {
await authok.loginWithRedirect({
redirect_uri: window.location.origin
});
};

更新 app.jswindow.onload函数:

public/js/app.js
// ..

window.onload = async () => {
// ..
updateUI();

const isAuthenticated = await authok.isAuthenticated();

if (isAuthenticated) {
return;
}

// NEW - 检查 code 和 state 参数
const query = window.location.search;
if (query.includes("code=") && query.includes("state=")) {
// 处理登录状态
await authok.handleRedirectCallback();

updateUI();

// 使用 replaceState 方法进行重定向 并移除 查询参数
window.history.replaceState({}, document.title, "/");
}
};

// ..

退登

public/js/app.js
const logout = () => {
authok.logout({
returnTo: window.location.origin
});
};

读取用户信息

index.html
<body>
<!-- ... -->
<div class="hidden" id="gated-content">
<p>
<strong>您已已登录</strong>.
</p>
<label>
Access token:
<pre id="ipt-access-token"></pre>
</label>
<label>
用户信息:
<pre id="ipt-user-profile"></pre>
</label>
</div>

<!-- .. existing script tags .. -->
</body>

修改 app.js 文件的 updateUI() 方法:

public/js/app.js
// ...
const updateUI = async () => {
const isAuthenticated = await authok.isAuthenticated();

document.getElementById("btn-logout").disabled = !isAuthenticated;
document.getElementById("btn-login").disabled = isAuthenticated;

// NEW - add logic to show/hide gated content after authentication
if (isAuthenticated) {
document.getElementById("gated-content").classList.remove("hidden");

document.getElementById(
"ipt-access-token"
).innerHTML = await authok.getTokenSilently();

document.getElementById("ipt-user-profile").textContent = JSON.stringify(
await authok.getUser()
);

} else {
document.getElementById("gated-content").classList.add("hidden");
}
};

// ..