Что касается механизма аутентификации Token, здесь не дается никаких дополнительных пояснений. Если вы не уверены, вы можете прочитать эту мою статью:Общие механизмы аутентификации в веб-разработке
Адрес гитхаба:koa-jwt-sample
требуемая библиотека
- bcrypt — для шифрования паролей
- koa-jwt — промежуточное ПО jwt
- jsonwebtoken — используется для генерации токена и отправки его в браузер.Метод jsonwebtoken больше не предоставляется в версиях после koa2, поэтому его нужно устанавливать отдельно.
Реализовать идеи
Процесс и идеи реализации всего решения предельно понятны, его можно условно разделить на следующие этапы:
- Пользовательское промежуточное ПО для перехвата 401 для перехвата, когда токен не существует или недействителен.
- Настроить коа-jwt
- Регистрация достижения
- Реализация входа
запустить проект
Этот проект требует, чтобы у вас был установлен и запущен mongodb. Для настройки mongodb см.config/index.js
.
npm run start
Проект предоставляет три API
- /api/register
- /api/login
- /api/users
в/api/register
а также/api/login
Это общедоступный API, к которому можно получить доступ без токена./users
Если это частный API, вам нужно передать правильный токен, чтобы получить к нему доступ.
Пользовательский обработчик 401
использовалkoa-jwt
После промежуточного программного обеспечения, если маркер отсутствует или токен недействителен, промежуточное программное обеспечение выдаст соответствующее сообщение об ошибке. Если пользовательского промежуточного программного обеспечения нет, оно будет напрямуюkoa-jwt
Информация об обнаруженной ошибке возвращается непосредственно пользователю.
// server/middlewares/errorHandle.js
export default errorHandle = (ctx, next) => {
return next().catch((err) => {
if (err.status === 401) {
ctx.status = 401;
ctx.body = {
error: err.originalError ? err.originalError.message : err.message,
};
} else {
throw err;
}
});
}
затем вindex.js
использовать это промежуточное ПО в
app
.use(errorHandle)
Используйте коа-jwt
существуетindex.js
Присоединяйсяkoa-jwt
промежуточное ПО.
const secert = 'jwt_secret'
app
.use(jwt({
secret,
}).unless({
path: [/\/register/, /\/login/],
}))
вsecret
Является ли ключ, используемый для шифрования, не ограничивается строкой, но также и файлом.
// https://github.com/koajs/jwt#token-verification-exceptions
var publicKey = fs.readFileSync('/path/to/public.pub');
app.use(jwt({ secret: publicKey }));
unless()
Используется для указания того, какие API не требуют проверки токена. То есть то, что мы обычно называем публичным API, API, к которому можно получить доступ без входа в систему. В этом примере установите/register
а также/login
Оба API не требуют проверки токена.
В использованииkoa-jwt
После всех маршрутов (кромеunless()
кроме заданного маршрута) проверимHeader
Существует ли токен в заголовке и является ли он действительным. Только после правильного можно исправить доступ.
регистрация реализации
Регистрация очень проста, здесь достаточно просто зашифровать пароль и сохранить информацию в базе данных. В реальных проектах также необходимо проверять поля, введенные пользователем.
/**
* you can register with
* curl -X POST http://localhost:3200/api/register -H 'cache-control: no-cache' -H 'content-type: application/x-www-form-urlencoded' -d 'username=superman2&password=123456'
*/
async register(ctx) {
const { body } = ctx.request;
try {
if (!body.username || !body.password) {
ctx.status = 400;
ctx.body = {
error: `expected an object with username, password but got: ${body}`,
}
return;
}
body.password = await bcrypt.hash(body.password, 5)
let user = await User.find({ username: body.username });
if (!user.length) {
const newUser = new User(body);
user = await newUser.save();
ctx.status = 200;
ctx.body = {
message: '注册成功',
user,
}
} else {
ctx.status = 406;
ctx.body = {
message: '用户名已经存在',
}
}
} catch (error) {
ctx.throw(500)
}
}
Реализация входа
Пользователь вводит имя пользователя и пароль для входа в систему, если имя пользователя и пароль верны, используйтеjsonwebtoken.sign()
Сгенерируйте токен и верните его клиенту. Клиент сохраняет токен в локальном хранилище, и в каждом HTTP-запросе токен добавляется в заголовок HTTP.Authorazition: Bearer token
середина. Затем серверная часть каждый раз проверяет правильность токена. Только после того, как токен будет правильным, можно получить доступ к соответствующему ресурсу.
/** you can login with
* curl -X POST http://localhost:3200/api/login/ -H 'cache-control: no-cache' -H 'content-type: application/x-www-form-urlencoded' -d 'username=superman2&password=123456'
*/
async login(ctx) {
const { body } = ctx.request
try {
const user = await User.findOne({ username: body.username });
if (!user) {
ctx.status = 401
ctx.body = {
message: '用户名错误',
}
return;
}
// 匹配密码是否相等
if (await bcrypt.compare(body.password, user.password)) {
ctx.status = 200
ctx.body = {
message: '登录成功',
user: user.userInfo,
// 生成 token 返回给客户端
token: jsonwebtoken.sign({
data: user,
// 设置 token 过期时间
exp: Math.floor(Date.now() / 1000) + (60 * 60), // 60 seconds * 60 minutes = 1 hour
}, secret),
}
} else {
ctx.status = 401
ctx.body = {
message: '密码错误',
}
}
} catch (error) {
ctx.throw(500)
}
}
Следует отметить, что при использованииjsonwebtoken.sign()
когда входящийsecret
параметры, здесьsecret
Должен быть установлен с предыдущимjwt()
серединаsecret
Последовательный.
больше оjsonwebtoken
метод см.:GitHub.com/AUTH0/узел-…
После входа в систему возьмите возвращенный токен и посетите этот раз/api/users
, вы можете правильно получить список пользователей.
curl -X GET http://localhost:3200/api/users -H 'authorization: Bearer token' -H 'cache-control: no-cache'