【发布时间】:2019-11-22 08:15:12
【问题描述】:
我正在尝试实现一个注册和登录系统,目前我能够在数据库中注册和存储数据并登录,因为我已经测试过它,我使用console.log(token); 来查看我是否是一个令牌.然而,在登录后,我进入了我的网页(React 组件)/Profile,它获取了一个 GET users/current,但我在控制台中收到了这个。
GET /users/current 401 2.083 ms - 33
也在我的浏览器控制台中
Uncaught (in promise) SyntaxError: Unexpected token A in JSON at position 0
我觉得令牌没有正确传递,我是使用 JWT 的新手,所以任何帮助都很有用。
服务器.js
var express = require('express');
var cors = require('cors');
var bodyParser = require('body-parser');
var app = express();
var port = process.env.PORT || 5000;
var morgan = require('morgan');
const auth = require('./middleware/auth');
const User = require('./models/User');
app.use(bodyParser.json());
app.use(cors());
app.use(
bodyParser.urlencoded({
extended: false
})
);
// use morgan to log requests to the console
app.use(morgan('dev'));
var Users = require('./routes/Users');
app.use('/users', Users);
// Create a Server
const PORT = process.env.PORT || 5000; // Environment variable or port 5000
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
用户.js
const express = require('express');
const users = express.Router();
const cors = require('cors');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');
const bodyParser = require('body-parser');
const User = require('../models/User');
const config = require('config');
const auth = require('../middleware/auth');
users.use(
bodyParser.urlencoded({
extended: true
})
);
users.use(bodyParser.json());
users.use(cors());
users.post('/register', (req, res) => {
const today = new Date();
const userData = {
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: req.body.password,
created: today
};
User.findOne({
where: {
email: req.body.email
}
})
//TODO bcrypt
//Need validation to appear on console and in view
.then(user => {
if (!user) {
bcrypt.hash(req.body.password, 10, (err, hash) => {
userData.password = hash;
User.create(userData)
.then(user => {
res.json({ status: user.email + 'Registered!' });
})
.catch(err => {
res.send('error: ' + err);
});
});
} else {
res.json({ error: 'User already exists' });
}
})
.catch(err => {
res.send('error: ' + err);
});
});
users.post('/authenticate', (req, res) => {
User.findOne({
where: {
email: req.body.email
}
}).then(user => {
if (user) {
if (bcrypt.compareSync(req.body.password, user.password)) {
const payload = {
check: true
};
const token = jwt.sign(payload, config.get('myprivatekey'), {
expiresIn: 1440 // expires in 24 hours
});
res.json({
message: 'authentication done ',
token: token
});
console.log('Successful Login');
console.log(user.first_name);
} else {
res.json({ message: 'please check your password !' });
console.log('incorrect password');
}
} else {
res.json({ message: 'user not found !' });
console.log('user cannot be found');
}
});
});
users.get('/current', auth, async (req, res) => {
const user = await User.findById(req.user._id).select('-password');
console.log(user);
res.send(user);
});
Auth.js
const jwt = require('jsonwebtoken');
const config = require('config');
module.exports = function(req, res, next) {
//get the token from the header if present
const token = req.headers['x-access-token'] || req.headers['authorization'];
//if no token found, return response (without going to the next middelware)
if (!token) return res.status(401).send('Access denied. No token provided.');
try {
//if can verify the token, set req.user and pass to next middleware
const decoded = jwt.verify(token, config.get('myprivatekey'));
req.user = decoded;
next();
} catch (ex) {
//if invalid token
res.status(400).send('Invalid token.');
}
};
/Profile 网页(React 组件)
import React, { Component } from 'react';
import jwt_decode from 'jwt-decode';
import axios from 'axios';
class Profile extends Component {
constructor() {
super();
this.state = {
first_name: '',
last_name: '',
email: '',
errors: {}
};
}
componentDidMount() {
fetch('http://localhost:5000/users/current')
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(JSON.stringify(myJson));
});
}
render() {
return (
<div className='container'>
<div className='jumbotron mt-5'>
<div className='col-sm-8 mx-auto'>
<h1 className='text-center'>PROFILE</h1>
</div>
<table className='table col-md-6 mx-auto'>
<tbody>
<tr>
<td>First Name</td>
<td>{this.state.first_name}</td>
</tr>
<tr>
<td>Last Name</td>
<td>{this.state.last_name}</td>
</tr>
<tr>
<td>Email</td>
<td>{this.state.email}</td>
</tr>
</tbody>
</table>
</div>
</div>
);
}
}
export default Profile;
【问题讨论】:
-
Offtopic:请记住,jwt 可以被暴力破解,当这种情况发生时,攻击者可以创建自己的 jwt 并对其进行签名..
-
@RaymondNijland 你有什么建议?
-
而不是使用 JWT 登录。会话更好吗?
-
研究一些算法容易出现的问题
-
代码的哪一行出现语法错误?