koa реализует аутентификацию jwt

Node.js внешний интерфейс API koa

Что касается механизма аутентификации 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'