- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的 SPA 有一个工作组件,用于获取访问 token ,该 token 将被加密并通过 props
传递给其他组件。就是这样:
import React, { Component } from 'react';
//import { Redirect } from 'react-router-dom';
import axios from 'axios';
import Credentials from './spotify-auth.js'
import './Spotify.css'
class SpotifyAuth extends Component {
constructor (props) {
super(props);
this.state = {
isAuthenticatedWithSpotify: false,
};
this.state.handleRedirect = this.handleRedirect.bind(this);
};
generateRandomString(length) {
let text = '';
const possible =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (let i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
getHashParams() {
const hashParams = {};
const r = /([^&;=]+)=?([^&;]*)/g;
const q = window.location.hash.substring(1);
let e = r.exec(q);
while (e) {
hashParams[e[1]] = decodeURIComponent(e[2]);
e = r.exec(q);
}
return hashParams;
}
componentDidMount() {
//if (this.props.isAuthenticated) {
const params = this.getHashParams();
const access_token = params.access_token;
const state = params.state;
const storedState = localStorage.getItem(Credentials.stateKey);
localStorage.setItem('spotifyAuthToken', access_token);
localStorage.getItem('spotifyAuthToken');
if (window.localStorage.getItem('authToken')) {
this.setState({ isAuthenticatedWithSpotify: true });
};
if (access_token && (state == null || state !== storedState)) {
alert('Click "ok" to finish authentication with Spotify');
} else {
localStorage.removeItem(Credentials.stateKey);
}
// DO STUFF WITH ACCEES TOKEN HERE
this.props.onConnectWithSpotify(access_token);
};
handleRedirect(event) {
event.preventDefault()
this.props.createMessage('You linked your Spotify account!', 'success');
// get client features at authenticating
const params = this.getHashParams();
const access_token = params.access_token;
console.log(access_token);
const state = this.generateRandomString(16);
localStorage.setItem(Credentials.stateKey, state);
let url = 'https://accounts.spotify.com/authorize';
url += '?response_type=token';
url += '&client_id=' + encodeURIComponent(Credentials.client_id);
url += '&scope=' + encodeURIComponent(Credentials.scope);
url += '&redirect_uri=' + encodeURIComponent(Credentials.redirect_uri);
url += '&state=' + encodeURIComponent(state);
window.location = url;
};
render() {
return (
<div className="button_container">
<h1 className="title is-3"><font color="#C86428">{"Welcome"}</font></h1>
<div className="Line" /><br/>
<button className="sp_button" onClick={(event) => this.handleRedirect(event)}>
<strong>LINK YOUR SPOTIFY ACCOUNT</strong>
</button>
</div>
)
}
}
export default SpotifyAuth;
<小时/>
此 token 凭据持续 60 分钟。
我了解到 SPA 的标准选项是使用 iframe
静默更新 token ,而根本不使用刷新 token 。
如何在像上面这样的 React 组件中启动 iframe
并每小时默默地获取一个新的访问 token ?我到处寻找这个,但没有找到任何东西。
最佳答案
您可以执行以下操作:
redirect.html
。服务器应该从存储的 cookie 中了解调用此 URL 的用户,因此它应该只是将您重定向到 redirect.html
文件,现在带有新的访问 token 。redirect.html
编写一个简短的脚本,从 URL 中取出 token 并用本地存储中已有的 token 覆盖它。就这样了,token更新了。保持观察者继续运行并在每次即将到期时更新(例如在到期前 5 分钟进行)。
React 中 AccessToken 组件的示例实现,大部分代码实际上都可以工作,但是您需要用您的东西替换常量。另外,一些函数如 extractTokenFromUrl
缺少,但这应该很容易制作:
import React, { Component } from 'react'
export class SilentTokenRenew extends Component {
constructor(props) {
super(props)
this.state = { renewing: false }
this.currentAttempt = 0
this.maxNumberOfAttempts = 20
}
shouldComponentUpdate(nextProps, nextState) {
return this.state.renewing !== nextState.renewing
}
componentDidMount() {
this.timeInterval = setInterval(this.handleCheckToken, 20000)
}
componentWillUnmount() {
clearInterval(this.timeInterval)
}
willTokenExpire = () => {
const token = YOUR_ACCESS_TOKEN_OBJECT // { accessToken, expirationTime }
const threshold = 300 // 300s = 5 minute threshold for token expiration
const hasToken = token && token.accessToken
const now = (Date.now() / 1000) + threshold
return !hasToken || (now > token.accessToken.expirationTime)
}
handleCheckToken = () => {
if (this.willTokenExpire()) {
this.setState({ renewing: true })
clearInterval(this.timeInterval)
}
}
silentRenew = () => {
return new Promise((resolve, reject) => {
const checkRedirect = () => {
// This can be e
const redirectUrl = localStorage[YOUR_REDIRECT_URL_FROM_THE_REDIRECT_HTML_FILE] // /redirect.html#access_token=......
if (!redirectUrl) {
this.currentAttempt += 1
if (this.currentAttempt > this.maxNumberOfAttempts) {
reject({
message: 'Silent renew failed after maximum number of attempts.',
short: 'max_number_of_attempts_reached',
})
return
}
setTimeout(() => checkRedirect(), 500)
return
}
// Clean up your localStorage for the next silent renewal
localStorage.removeItem(YOUR_REDIRECT_URL_FROM_THE_REDIRECT_HTML_FILE)
// Put some more error handlers here
// Silent renew worked as expected, lets update the access token
const session = extractTokenFromUrl(redirectUrl) // write some function to get out the access token from the URL
// Following your code you provided, here is the time to set
// the extracted access token back to your localStorage under a key Credentials.stateKey
localStorage.setItem(Credentials.stateKey, JSON.stringify(session))
resolve(session)
}
checkRedirect()
})
}
handleOnLoad = () => {
this.silentRenew()
.then(() => {
this.setState({ renewing: false })
this.currentAttempt = 0
this.timeInterval = setInterval(this.handleCheckToken, 60000)
// Access token renewed silently.
})
.catch(error => {
this.setState({ renewing: false })
// handle the errors
})
}
renderIframe = () => {
const url = new URL(YOUR_AUTHORIZE_URL_TO_TH_AUTH_SERVER)
url.searchParams.set('redirect_uri', 'http://localhost:3000/redirect.html') // the redirect.html file location
url.searchParams.set('prompt', 'none')
return (
<iframe
style={{ width: 0, height: 0, position: 'absolute', left: 0, top: 0, display: 'none', visibility: 'hidden' }}
width={0}
height={0}
title="silent-token-renew"
src={url.href}
onLoad={this.handleOnLoad}
/>
)
}
render() {
const { renewing } = this.state
return renewing ? this.renderIframe() : null
}
}
redirect.html
前面的示例代码文件:
<!DOCTYPE html>
<html>
<head>
<title>OAuth - Redirect</title>
</head>
<body>
<p>Renewing...</p>
<script>
// Get name of window which was set by the parent to be the unique request key
// or if no parameter was specified, we have a silent renew from iframe
const requestKey = YOUR_REDIRECT_URL_FROM_THE_REDIRECT_HTML_FILE;
// Update corresponding entry with the redirected url which should contain either access token or failure reason in the query parameter / hash
window.localStorage.setItem(requestKey, window.location.href);
window.close();
</script>
</body>
</html>
关于javascript - ReactJS - 使用 iframe 静默更新 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60307383/
我正在开发一个应用程序,它使用 OAuth - 基于 token 的身份验证。 考虑到我们拥有访问和刷新 token ,这就是流程的样子。 Api call -> intercepter append
如何取消标记此代码的输出? 类(class)核心: def __init__(self, user_input): pos = pop(user_input) subject = ""
当我使用命令 kubectl 时与 --token标记并指定 token ,它仍然使用 kubeconfig 中的管理员凭据文件。 这是我做的: NAMESPACE="default" SERVICE
我正在制作 SPA,并决定使用 JWT 进行身份验证/授权,并且我已经阅读了一些关于 Tokens 与 Cookies 的博客。我了解 cookie 授权的工作原理,并了解基本 token 授权的工作
我正在尝试从应用服务获取 Google 的刷新 token ,但无法。 日志说 2016-11-04T00:04:25 PID[500] Verbose Received request: GET h
我正在开发一个项目,只是为了为 java 开发人员测试 eclipse IDE。我是java新手,所以我想知道为什么它不起作用,因为我已经知道该怎么做了。这是代码: public class ecli
我正在尝试使用 JwtSecurityTokenHandler 将 token 字符串转换为 jwt token 。但它出现错误说 IDX12709: CanReadToken() returned
我已阅读文档 Authentication (来自 Facebook 的官方)。我仍然不明白 Facebook 提供的这三种访问 token 之间的区别。网站上给出了一些例子,但我还是不太明白。 每个
我的部署服务器有时有这个问题,这让我抓狂,因为我无法在本地主机中重现,我已经尝试在我的 web.config 中添加机器 key ,但没有成功远。 它只发生在登录页面。 我的布局:
我已经设法获得了一个简单的示例代码,它可以创建一个不记名 token ,还可以通过阅读 stackoverflow 上的其他论坛来通过刷新 token 请求新的不记名 token 。 启动类是这样的
如果我有以前的刷新 token 和使用纯 php 的访问 token ,没有 Google Api 库,是否可以刷新 Google Api token ?我在数据库中存储了许多用户刷新和访问 toke
我通过 Java 应用程序使用 Google 电子表格时遇到了问题。我创建了应用程序,该应用程序运行了 1 年多,没有任何问题,我什至在 Create Spreadsheet using Google
当我有一个有效的刷新 token 时,我正在尝试使用 Keycloak admin REST API 重新创建访问 token 。 我已经通过调用 POST/auth/realms/{realm}/p
我正在尝试让第三方 Java 客户端与我编写的 WCF 服务进行通信。 收到消息时出现如下异常: Cannot find a token authenticator for the 'System.I
在尝试将数据插入到我的 SQl 数据库时,我收到以下错误 System.Data.SqlServerCe.SqlCeException: There was an error parsing the
使用数据库 session token 系统,我可以让用户使用用户名/密码登录,服务器可以生成 token (例如 uuid)并将其存储在数据库中并将该 token 返回给客户端。其上的每个请求都将包
我最近注册了 Microsoft Azure 并设置了认知服务帐户。使用 Text Translation API Documentation 中的说明我能够使用 interactive online
我使用 IAntiforgery API 创建了一个 ASP.Net Core 2 应用程序。 这提供了一种返回 cookie 的方法。 客户端获取该 cookie,并在后续 POST 请求中将该值放
我正在使用 spacy 来匹配某些文本(意大利语)中的特定表达式。我的文本可以多种形式出现,我正在尝试学习编写一般规则的最佳方式。我有如下 4 个案例,我想写一个适用于所有案例的通用模式。像这样的东西
我无法理解 oauth 2.0 token 的原则处理。 我的场景是,我有一个基于 web 的前端后端系统,带有 node.js 和 angular 2。用户应该能够在此站点上上传视频。然后创建一些额
我是一名优秀的程序员,十分优秀!