Guest User

Untitled

a guest
Jul 20th, 2018
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.22 KB | None | 0 0
  1. import * as Koa from 'koa';
  2. import * as Router from 'koa-router';
  3. import * as bodyParser from 'koa-bodyparser';
  4. import * as jwt from 'jsonwebtoken';
  5. // dotenv - пакет, который читает `.env` файл и сеттит `key-value` из файла в `process.env`
  6. import { config } from 'dotenv';
  7. import { compare } from 'bcrypt';
  8.  
  9. // Секретный ключ для хеширования и наоборот, можете сгенерить его на любом сами и засеттить в `.env` файл `SECRET=some_key`
  10. const { SECRET } = process.env;
  11.  
  12. const compareAsync = (data: string, encrypted: string): Promise<boolean> => {
  13. return new Promise((resolve, reject) => {
  14. compare(data, encrypted, (error: Error, same: boolean) => {
  15. if (error) {
  16. reject(error);
  17. }
  18.  
  19. resolve(same);
  20. });
  21. });
  22. };
  23.  
  24. const app = new Koa();
  25.  
  26. app.use(bodyParser());
  27.  
  28. const router = new Router({
  29. prefix: '/api'
  30. });
  31.  
  32. router.post('/login', async (ctx: Context) => {
  33. // Юзер логинится и шлет запрос на `/api/login`
  34. // с username + password
  35. const { username, password } = ctx.request.body;
  36.  
  37. // Попытаемся вытащить юзера из базы с таким `username`
  38. const { rows } = await client.query(`
  39. SELECT * FROM users WHERE username = $1
  40. `, [username]);
  41.  
  42. // Если такого пользователя нету
  43. if (rows.length === 0) {
  44. ctx.body = {
  45. message: `User with username '${username}' doesn't exist`
  46. };
  47. // Вернем статус `UNPROCESSABLE_ENTITY`
  48. return ctx.status = 422;
  49. }
  50.  
  51. const user = rows[0];
  52. // Сверяем пароли
  53. const same = await compareAsync(password, user.password);
  54.  
  55. if (!same) {
  56. ctx.body = {
  57. message: 'Invalid credentials'
  58. };
  59. return ctx.status = 422;
  60. }
  61.  
  62. // Если такой юзер существует, то берем его `id` и хешируем в токене
  63. const { id } = user;
  64. const token = jwt.sign({
  65. id
  66. }, SECRET_KEY, {
  67. expiresIn: 864e5 // 1 день
  68. });
  69.  
  70. // Далее сеттим токен в куках с флагом `httpOnly`, так безопаснее так как клиент не имеет доступ к ним
  71. ctx.cookies.set('Authorization', `Bearer ${token}`, {
  72. httpOnly: true,
  73. expires: new Date(new Date().valueOf() + 864e5),
  74. secure: true // 1 день
  75. });
  76. ctx.body = {
  77. id,
  78. email,
  79. username
  80. };
  81. });
  82.  
  83. import { verify } from 'jsonwebtoken';
  84. import { config } from 'dotenv';
  85.  
  86. const { SECRET } = process.env;
  87.  
  88. export const authMiddleware = async (ctx: Context, next: () => Promise<void>): Promise<void> => {
  89. const authorization = ctx.cookies.get('Authorization');
  90.  
  91. if (!authorization) {
  92. return ctx.status = 401;
  93. }
  94.  
  95. const token: string = authorization.split(' ')[1];
  96.  
  97. try {
  98. verify(token, SECRET);
  99.  
  100. return next();
  101. } catch (e) {
  102. return ctx.status = 401;
  103. }
  104. };
  105.  
  106. import { authMiddleware } from './authMiddleware.ts';
  107.  
  108. ......
  109.  
  110. router.get('/users', authMiddleware, async (ctx) .....)
Add Comment
Please, Sign In to add comment