Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as Koa from 'koa';
- import * as Router from 'koa-router';
- import * as bodyParser from 'koa-bodyparser';
- import * as jwt from 'jsonwebtoken';
- // dotenv - пакет, который читает `.env` файл и сеттит `key-value` из файла в `process.env`
- import { config } from 'dotenv';
- import { compare } from 'bcrypt';
- // Секретный ключ для хеширования и наоборот, можете сгенерить его на любом сами и засеттить в `.env` файл `SECRET=some_key`
- const { SECRET } = process.env;
- const compareAsync = (data: string, encrypted: string): Promise<boolean> => {
- return new Promise((resolve, reject) => {
- compare(data, encrypted, (error: Error, same: boolean) => {
- if (error) {
- reject(error);
- }
- resolve(same);
- });
- });
- };
- const app = new Koa();
- app.use(bodyParser());
- const router = new Router({
- prefix: '/api'
- });
- router.post('/login', async (ctx: Context) => {
- // Юзер логинится и шлет запрос на `/api/login`
- // с username + password
- const { username, password } = ctx.request.body;
- // Попытаемся вытащить юзера из базы с таким `username`
- const { rows } = await client.query(`
- SELECT * FROM users WHERE username = $1
- `, [username]);
- // Если такого пользователя нету
- if (rows.length === 0) {
- ctx.body = {
- message: `User with username '${username}' doesn't exist`
- };
- // Вернем статус `UNPROCESSABLE_ENTITY`
- return ctx.status = 422;
- }
- const user = rows[0];
- // Сверяем пароли
- const same = await compareAsync(password, user.password);
- if (!same) {
- ctx.body = {
- message: 'Invalid credentials'
- };
- return ctx.status = 422;
- }
- // Если такой юзер существует, то берем его `id` и хешируем в токене
- const { id } = user;
- const token = jwt.sign({
- id
- }, SECRET_KEY, {
- expiresIn: 864e5 // 1 день
- });
- // Далее сеттим токен в куках с флагом `httpOnly`, так безопаснее так как клиент не имеет доступ к ним
- ctx.cookies.set('Authorization', `Bearer ${token}`, {
- httpOnly: true,
- expires: new Date(new Date().valueOf() + 864e5),
- secure: true // 1 день
- });
- ctx.body = {
- id,
- email,
- username
- };
- });
- import { verify } from 'jsonwebtoken';
- import { config } from 'dotenv';
- const { SECRET } = process.env;
- export const authMiddleware = async (ctx: Context, next: () => Promise<void>): Promise<void> => {
- const authorization = ctx.cookies.get('Authorization');
- if (!authorization) {
- return ctx.status = 401;
- }
- const token: string = authorization.split(' ')[1];
- try {
- verify(token, SECRET);
- return next();
- } catch (e) {
- return ctx.status = 401;
- }
- };
- import { authMiddleware } from './authMiddleware.ts';
- ......
- router.get('/users', authMiddleware, async (ctx) .....)
Add Comment
Please, Sign In to add comment