使用 SvelteKit 的 Auth0 服务器端身份验证
Auth0 Server Side Authentication with SvelteKit
我知道没有官方的 Auth0 SvelteKit 插件可以直接使用,所以我尝试使用 JS 中的基本 API 函数实现手动方法进行服务器端身份验证和会话管理,使用 auth0.js 版本 9.11.
使用以下页面,我可以将用户重定向到Auth0通用登录页面,用户登录成功后重定向到我的登陆页面。我的计划是从页面上的用户令牌获取用户详细信息,然后将这些详细信息发送到服务器端点。在端点中,我会将这些详细信息保存到数据库(使用访问令牌)以进行登录会话管理,然后发送一个 HttpOnly
cookie 用于 auth guards..etc.
但是,我在着陆页中不断收到以下错误消息:
Uncaught (in promise) TypeError: can't assign to property "__enableIdPInitiatedLogin" on "#access_token=eyJhbGciOi...<very long token>...BNW1uzA&scope=openid%20profile%20email&expires_in=7200&token_type=Bearer&state=rtre4": not an object
用于获取用户详细信息但不起作用的代码如下:
<script lang="ts">
import { onMount } from 'svelte';
onMount(async () => {
// Initialize the Auth0 application
var webAuth = new auth0.WebAuth({
domain: '<domain>',
clientID: '<clientId>'
});
//test
console.log(window.location.hash);
// Parse the URL and extract the Access Token
webAuth.parseHash(window.location.hash, function (err, authResult) {
if (err) {
return console.log(err);
}
// webAuth.client.userInfo(authResult.accessToken, function (err, user) {
// // This method will make a request to the /userinfo endpoint
// // and return the user object, which contains the user's information,
// // similar to the response below.
// });
});
});
</script>
<svelte:head>
<script src="https://cdn.auth0.com/js/auth0/9.11/auth0.min.js"></script>
</svelte:head>
<div class="content">
<p>Redirecting, please wait...</p>
</div>
将用户重定向到通用登录页面的代码如下:
<script lang="ts">
import Button from '@smui/button';
const login = () => {
// Initialize app - auth0 is defined as external script in <svelte:head>
var webAuth = new auth0.WebAuth({
domain: '<domain>,
clientID: '<clientid>'
});
// Calculate URL to redirect to
var url = webAuth.client.buildAuthorizeUrl({
clientID: '<clientid>', // string
responseType: 'token id_token', // code or token
redirectUri: 'http://localhost:3000/login',
scope: 'openid profile email',
state: '<state>',
nonce: '<nonce>'
});
window.location = url;
}
</script>
<svelte:head>
<script src="https://cdn.auth0.com/js/auth0/9.11/auth0.min.js"></script>
</svelte:head>
<div class="content">
<Button on:click={login}>Login</Button>
</div>
EDIT 我根据 Kalana 的评论将 id_token
添加到登录 url 构造中(这也需要 nonce
参数)和根据新代码修改错误截图
经过更多的挖掘,我意识到提供给 parseHash
函数的选项需要是一个 JSON 对象。您还需要在创建登录请求时包含 id_token
(感谢 Kalana 的评论),以及 nonce
参数。您也必须为 parseHash
函数提供相同的 state
和 nonce
值。此外,此功能的 hash
是可选的;如果给出 none 它可以自动从 windows.location.hash
中获取它。
最后Auth0服务获取用户信息的工作代码如下:
<script lang="ts">
import { onMount } from 'svelte';
onMount(async () => {
// Initialize the Auth0 application
var webAuth = new auth0.WebAuth({
domain: '<domain>',
clientID: '<clientid>'
});
// Parse the URL and extract the Access Token
webAuth.parseHash({state: "<sameState>", nonce: "<sameNonce>"}, function (err, authResult) {
if (err) {
return console.log(err);
}
webAuth.client.userInfo(authResult.accessToken, function (innerErr, user) {
// This method will make a request to the /userinfo endpoint
// and return the user object, which contains the user's information,
// similar to the response below.
if (innerErr) {
return console.log(innerErr);
}
console.log(user);
});
});
});
</script>
<svelte:head>
<script src="https://cdn.auth0.com/js/auth0/9.11/auth0.min.js"></script>
</svelte:head>
<div class="content">
<p>Redirecting, please wait...</p>
</div>
我知道没有官方的 Auth0 SvelteKit 插件可以直接使用,所以我尝试使用 JS 中的基本 API 函数实现手动方法进行服务器端身份验证和会话管理,使用 auth0.js 版本 9.11.
使用以下页面,我可以将用户重定向到Auth0通用登录页面,用户登录成功后重定向到我的登陆页面。我的计划是从页面上的用户令牌获取用户详细信息,然后将这些详细信息发送到服务器端点。在端点中,我会将这些详细信息保存到数据库(使用访问令牌)以进行登录会话管理,然后发送一个 HttpOnly
cookie 用于 auth guards..etc.
但是,我在着陆页中不断收到以下错误消息:
Uncaught (in promise) TypeError: can't assign to property "__enableIdPInitiatedLogin" on "#access_token=eyJhbGciOi...<very long token>...BNW1uzA&scope=openid%20profile%20email&expires_in=7200&token_type=Bearer&state=rtre4": not an object
用于获取用户详细信息但不起作用的代码如下:
<script lang="ts">
import { onMount } from 'svelte';
onMount(async () => {
// Initialize the Auth0 application
var webAuth = new auth0.WebAuth({
domain: '<domain>',
clientID: '<clientId>'
});
//test
console.log(window.location.hash);
// Parse the URL and extract the Access Token
webAuth.parseHash(window.location.hash, function (err, authResult) {
if (err) {
return console.log(err);
}
// webAuth.client.userInfo(authResult.accessToken, function (err, user) {
// // This method will make a request to the /userinfo endpoint
// // and return the user object, which contains the user's information,
// // similar to the response below.
// });
});
});
</script>
<svelte:head>
<script src="https://cdn.auth0.com/js/auth0/9.11/auth0.min.js"></script>
</svelte:head>
<div class="content">
<p>Redirecting, please wait...</p>
</div>
将用户重定向到通用登录页面的代码如下:
<script lang="ts">
import Button from '@smui/button';
const login = () => {
// Initialize app - auth0 is defined as external script in <svelte:head>
var webAuth = new auth0.WebAuth({
domain: '<domain>,
clientID: '<clientid>'
});
// Calculate URL to redirect to
var url = webAuth.client.buildAuthorizeUrl({
clientID: '<clientid>', // string
responseType: 'token id_token', // code or token
redirectUri: 'http://localhost:3000/login',
scope: 'openid profile email',
state: '<state>',
nonce: '<nonce>'
});
window.location = url;
}
</script>
<svelte:head>
<script src="https://cdn.auth0.com/js/auth0/9.11/auth0.min.js"></script>
</svelte:head>
<div class="content">
<Button on:click={login}>Login</Button>
</div>
EDIT 我根据 Kalana 的评论将 id_token
添加到登录 url 构造中(这也需要 nonce
参数)和根据新代码修改错误截图
经过更多的挖掘,我意识到提供给 parseHash
函数的选项需要是一个 JSON 对象。您还需要在创建登录请求时包含 id_token
(感谢 Kalana 的评论),以及 nonce
参数。您也必须为 parseHash
函数提供相同的 state
和 nonce
值。此外,此功能的 hash
是可选的;如果给出 none 它可以自动从 windows.location.hash
中获取它。
最后Auth0服务获取用户信息的工作代码如下:
<script lang="ts">
import { onMount } from 'svelte';
onMount(async () => {
// Initialize the Auth0 application
var webAuth = new auth0.WebAuth({
domain: '<domain>',
clientID: '<clientid>'
});
// Parse the URL and extract the Access Token
webAuth.parseHash({state: "<sameState>", nonce: "<sameNonce>"}, function (err, authResult) {
if (err) {
return console.log(err);
}
webAuth.client.userInfo(authResult.accessToken, function (innerErr, user) {
// This method will make a request to the /userinfo endpoint
// and return the user object, which contains the user's information,
// similar to the response below.
if (innerErr) {
return console.log(innerErr);
}
console.log(user);
});
});
});
</script>
<svelte:head>
<script src="https://cdn.auth0.com/js/auth0/9.11/auth0.min.js"></script>
</svelte:head>
<div class="content">
<p>Redirecting, please wait...</p>
</div>