【发布时间】:2020-05-02 16:37:00
【问题描述】:
我是新手,我想将 JWT 身份验证添加到我的 SPA。我的目标是我在应用程序的本地存储中获取令牌但无法解码令牌。我无法弄清楚我哪里出错了。谁能帮我解码。这是我的 API -m5iZiI6MTU4ODQwNjQ5MywiZXhwIjoxNTg4NTc5MjkzLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjQ1MDkyLyIsImF1ZCI6Imh0dHA6Ly9sb2NhbGhvc3Q6NDUwOTIvIn0.MjmDKCoQoEOLKtoL_iUAAqE7hnE2xmUdnCB6JdaGX3w 生成的示例令牌。
这里是 AuthService 代码:
import decode from 'jwt-decode';
export default class AuthService {
constructor(domain) {
this.domain = domain || '/api/Login/auth'
this.fetch = this.fetch.bind(this) // React binding stuff
this.login = this.login.bind(this)
this.getProfile = this.getProfile.bind(this)
}
login = (email, password) => {
return this.fetch(`${this.domain}`, {
method: 'POST',
body: JSON.stringify({
email,
password
})
}).then(res => {
this.setToken(res.token)
return Promise.resolve(res);
})
}
loggedIn () {
const token = this.getToken()
return !!token && !this.isTokenExpired(token)
}
isTokenExpired (token) {
try {
const decoded = decode(token);
if (decoded.exp < Date.now() / 1000) {
return true;
}
else
return false;
}
catch (err) {
return false;
}
}
setToken (idToken) {
localStorage.setItem('id_token', idToken)
console.log("token values", idToken)
}
getToken () {
return localStorage.getItem('id_token')
}
logout () {
localStorage.removeItem('id_token');
}
getProfile () {
return decode(this.getToken());
}
fetch (url, options) {
const headers = {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
if (this.loggedIn()) {
headers['Authorization'] = 'Bearer ' + this.getToken()
}
return fetch(url, {
headers,
...options
})
.then(this._checkStatus)
.then(response => response.json())
}
_checkStatus (response) {
if (response.status >= 200 && response.status < 300) {
return response
} else {
var error = new Error(response.statusText)
error.response = response
throw error
}
}
}
Login.js 代码:
import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import Container from '@material-ui/core/Container';
import AuthService from '../../service/AuthService';
class LoginComponent extends React.Component {
constructor(props){
super(props);
this.state = {
username: '',
password: '',
message: '',
}
this.login = this.login.bind(this);
this.Auth = new AuthService();
}
componentWillMount () {
if (this.Auth.loggedIn())
this.props.history.replace('/');
}
login = (e) => {
e.preventDefault();
this.Auth.login(this.state.email, this.state.password).then(res => {
if(res.status === 200){
localStorage.setItem("userInfo", JSON.stringify(res));
this.props.history.push('/');
}else {
this.setState({message: res.data.message});
}
});
};
onChange = (e) =>
this.setState({ [e.target.name]: e.target.value });
render() {
return(
<React.Fragment>
<AppBar position="static">
<Toolbar>
<Typography variant="h6">
React User Application
</Typography>
</Toolbar>
</AppBar>
<Container maxWidth="sm">
<Typography variant="h4" style={styles.center}>Login</Typography>
<form>
<Typography variant="h4" style={styles.notification}>{this.state.message}</Typography>
<TextField type="text" label="USERNAME" fullWidth margin="normal" name="username" value={this.state.username} onChange={this.onChange}/>
<TextField type="password" label="PASSWORD" fullWidth margin="normal" name="password" value={this.state.password} onChange={this.onChange}/>
<Button variant="contained" color="secondary" onClick={this.login}>Login</Button>
</form>
</Container>
</React.Fragment>
)
}
}
const styles= {
center :{
display: 'flex',
justifyContent: 'center'
},
notification: {
display: 'flex',
justifyContent: 'center',
color: '#dc3545'
}
}
export default LoginComponent;
谁能帮助我或建议我任何合适的链接?
【问题讨论】:
-
你能添加生成令牌的代码吗?还要检查您是否在问题中添加了有效的标记,您添加的标记似乎不完整。
-
@SuleymanSah - 嗨,令牌是从后端(本地)生成的,我通过 api 链接获取令牌,即
/api/Login/auth。我已经更新了查询中的令牌值。 -
您在本地存储中看到令牌了吗?
-
@SuleymanSah - 是的,我在 localstorage 中获取令牌 - 即在 AuthService.js 中的 setToken() 函数中。
-
但是你检查了浏览器吗?你看到了吗?