node.js - 使用 React 的登录令牌
问题描述
我正在使用 React 连接登录功能,并且遇到了用户会话令牌的问题。
问题: 我能够成功登录并创建用户会话令牌(通过控制台验证),但是,一旦我在成功登录后刷新页面,它会将我重定向回登录页面,就好像我没有令牌一样。
为什么会出现这个令牌问题?它甚至是一个令牌问题吗?
我已经编写了 react 代码,如果 !token,则直接到登录表单,如果有令牌,则重定向到占位符('account')
import React, { Component } from 'react';
import { Form, Container, Button, Spinner } from 'react-bootstrap'
import { getFromStorage, setInStorage } from '../utils/storage'
export default class LoginUser extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
token: '',
logInError: '',
logInEmail: '',
logInPassword: '',
}
this.onChangeLogInEmail = this.onChangeLogInEmail.bind(this);
this.onChangeLogInPassword = this.onChangeLogInPassword.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.logout = this.logout.bind(this);
}
componentDidMount() {
const obj = getFromStorage('OI_Login')
if (obj && obj.token) {
const { token } = obj
// verify token
fetch('http://localhost:5001/users/verify?token' + token)
.then(res => res.json())
.then(json => {
if (json.success) {
this.setState({
token,
isLoading: false
})
} else {
this.setState({
isLoading: false
})
}
})
} else {
this.setState({
isLoading: false,
})
}
}
// ON CHANGE
onChangeLogInEmail(e) {
this.setState({
logInEmail: e.target.value
})
}
onChangeLogInPassword(e) {
this.setState({
logInPassword: e.target.value
})
}
logout(e) {
e.preventDefault()
this.setState({
isLoading: true,
})
const obj = getFromStorage('OI_Login')
if (obj && obj.token) {
const { token } = obj
// verify token
fetch('http://localhost:5001/users/logout?token' + token)
.then(res => res.json())
.then(json => {
if (json.success) {
this.setState({
token: '',
isLoading: false,
logInError: ''
})
} else {
this.setState({
isLoading: false
})
}
})
} else {
this.setState({
isLoading: false,
})
}
}
onSubmit(e) {
e.preventDefault()
const {
logInEmail,
logInPassword
} = this.state
this.setState({
isLoading: true,
})
//post request to backend
fetch('http://localhost:5001/users/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: logInEmail,
password: logInPassword
}),
}).then(res => res.json())
.then(json => {
if (json.success) {
setInStorage('OI_Login', { token: json.token })
this.setState({
logInError: json.message,
isLoading: false,
logInEmail: '',
logInPassword: '',
token: json.token
})
} else {
this.setState({
logInError: json.message,
isLoading: false
})
}
})
}
render() {
const {
isLoading,
token,
logInError,
logInEmail,
logInPassword,
} = this.state
if (isLoading) {
return (
<>
<div className="justify-content-center">
<Spinner animation="border" />
</div>
</>
)
}
if (!token) {
return (
<>
<Container>
<h3>Log In</h3>
<Form>
<Form.Group>
<Form.Label>Email</Form.Label>
<Form.Control
required
type="email"
id="email"
value={logInEmail}
onChange={this.onChangeLogInEmail}
/>
</Form.Group>
<Form.Group>
<Form.Label>Password</Form.Label>
<Form.Control
required
type="password"
id="password"
value={logInPassword}
onChange={this.onChangeLogInPassword}
/>
</Form.Group>
<div>
{
(logInError) ? (
<p>{logInError}</p>
) : (null)
}
</div>
<Form.Group>
<Button variant="btn btn-primary" onClick={this.onSubmit} type="submit">Log In</Button>
</Form.Group>
</Form>
<a href='/register'>Register</a>
</Container>
</>
)
}
return (
<>
<p>Account</p>
<Button variant="danger" onClick={this.logout}>Log Out</Button>
</>
)
}
}
代币存储
export function getFromStorage(key) {
if (!key) {
return null
}
try {
const valueStr = localStorage.getItem(key)
if (valueStr) {
return JSON.parse(valueStr)
}
return null
} catch (err) {
return null
}
}
export function setInStorage(key, obj) {
if (!key) {
console.error('Error: Key is missing')
}
try {
localStorage.setItem(key, JSON.stringify(obj))
} catch (err) {
console.error(err)
}
}
解决方案
You need to save the token to the cookie when you got it. And get the token from the cookie after page refreshing.
推荐阅读
- android - 该服务目前不可用 | Firebase cloud_firestore 问题
- python - 使用 web3.py 计算令牌对的 LP 地址
- linux - Centos7 Crontab 作业没有定期执行
- sql - 在 X 个不同日期玩过的用户 - SQL Standard + BigQuery
- react-native - 在 Fetch API 之外获取“未定义”值
- c# - 方法调用的替代方案
- c# - C# get Result from IF Statement
- flutter - My second container is taking all the space.How to avoid that
- javascript - 使用 vue-tables-2 将文本附加到列
- apache-spark - 如何解决 Spark 中的最大视图深度误差?