问题描述
我有一个SPA react应用程序,正在使用 auth0 进行身份验证。我想进行静默身份验证,并在每次刷新站点时获取一个新令牌,就像本answer中所建议的那样。 我有一个 Auth 类负责处理令牌:
import auth0 from 'auth0-js'
import { authConfig } from '../config'
export default class Auth {
accesstoken
idToken
expiresAt
auth0 = new auth0.WebAuth({
domain: authConfig.domain,clientID: authConfig.clientId,redirectUri: authConfig.callbackUrl,responseType: 'token id_token',scope: 'openid'
})
constructor(history) {
this.history = history
this.login = this.login.bind(this)
this.logout = this.logout.bind(this)
this.handleAuthentication = this.handleAuthentication.bind(this)
this.isAuthenticated = this.isAuthenticated.bind(this)
this.getAccesstoken = this.getAccesstoken.bind(this)
this.getIdToken = this.getIdToken.bind(this)
this.renewSession = this.renewSession.bind(this)
}
login() {
this.auth0.authorize()
}
handleAuthentication() {
this.auth0.parseHash((err,authResult) => {
if (authResult && authResult.accesstoken && authResult.idToken) {
console.log('Access token: ',authResult.accesstoken)
console.log('id token: ',authResult.idToken)
this.setSession(authResult)
} else if (err) {
this.history.replace('/')
console.log(err)
alert(`Error: ${err.error}. Check the console for further details.`)
}
})
}
getAccesstoken() {
return this.accesstoken
}
getIdToken() {
return this.idToken
}
setSession(authResult) {
// Set isLoggedIn flag in localStorage
localStorage.setItem('isLoggedIn','true')
// Set the time that the access token will expire at
let expiresAt = authResult.expiresIn * 1000 + new Date().getTime()
this.accesstoken = authResult.accesstoken
this.idToken = authResult.idToken
this.expiresAt = expiresAt
// navigate to the home route
this.history.replace('/')
}
renewSession(cb) {
this.auth0.checkSession({},(err,authResult) => {
if (authResult && authResult.accesstoken && authResult.idToken) {
this.setSession(authResult)
cb(err,authResult)
} else if (err) {
this.logout()
console.log(
`Could not get a new token (${err.error}: ${err.error_description}).`
)
}
})
}
logout() {
// Remove tokens and expiry time
this.accesstoken = null
this.idToken = null
this.expiresAt = 0
// Remove isLoggedIn flag from localStorage
localStorage.removeItem('isLoggedIn')
this.auth0.logout({
return_to: `${window.location.origin}/login`
})
}
isAuthenticated() {
// Check whether the current time is past the
// access token's expiry time
let expiresAt = this.expiresAt
return new Date().getTime() < expiresAt
}
}
在我的主要 App 组件的 componentDidMount 中,我正在从Auth类调用 renewSession 方法:
export default class App extends Component<AppProps,AppState> {
constructor(props: AppProps) {
super(props)
this.handleLogin = this.handleLogin.bind(this)
this.handlelogout = this.handlelogout.bind(this)
this.createNewPost = this.createNewPost.bind(this)
}
state: AppState = {
tokenRenewed: false
}
componentDidMount() {
this.props.auth.renewSession(() => {
this.setState({ tokenRenewed: true })
})
}
handleLogin() {
this.props.auth.login()
}
handlelogout() {
this.props.auth.logout()
}
async createNewPost() {
const idToken = this.props.auth.getIdToken()
try {
const newPost = await createPost(idToken)
this.props.history.push(`/posts/${newPost.postId}/edit`)
} catch {
alert('Post creation Failed')
}
}
render() {
if (!this.state.tokenRenewed) return 'loading...'
const userAuthenticated = this.props.auth.isAuthenticated()
return (
<div>
<Segment vertical>
<Grid container stackable verticalAlign="middle">
<Grid.Row>
<Grid.Column width={16}>
<Router history={this.props.history}>
{this.generateMenu(userAuthenticated)}
{this.generateCurrentPage(userAuthenticated)}
</Router>
</Grid.Column>
</Grid.Row>
</Grid>
</Segment>
</div>
)
}
这是我的路线:
<Router history={history}>
<Switch>
<Route
path="/callback"
render={props => {
handleAuthentication(props)
return <Callback />
}}
/>
<Route
path="/login"
render={props => {
return <LogIn auth={auth} {...props} />
}}
/>
<Route
path="/"
render={props => {
return <App auth={auth} {...props} />
}}
/>
</Switch>
</Router>
如果我使用用户名/密码登录,效果很好。但是,如果我使用Google / Gmail之类的社交登录名,则每当我登录该应用程序时,都会在 Auth 类的 auth0.checkSession 中收到错误消息:
我该如何同时使用Google / Gmail登录?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)