Не удается получить аутентификацию для работы с devise-jwt - PullRequest
1 голос
/ 16 апреля 2020

Я пытаюсь заставить работать devise и devise-jwt гемов, чтобы я мог реализовать авторизацию в своем приложении только для API Rails.

Я установил и devise, и devise-jwt гемы.

Я следовал инструкциям в этом сообщении:

https://medium.com/@mazik.wyry / rails-5-api-jwt-setup-in-minutes-using-devise-71670fd4ed03

Я реализовал спецификации запросов, которые автор включил в свой пост, и я не могу их передать. Если я вставлю в контроллер сеанса бибаг, я вижу, что он говорит: «Пользователь должен войти или зарегистрироваться перед тем, как продолжить».

Есть мысли о том, что я делаю неправильно?

Вот соответствующие файлы:

rout.rb

Rails.application.routes.draw do

  namespace :api, path: '', defaults: {format: :json} do
      namespace :v1 do
        devise_for :users,
                   path: '',
                   path_names: {
                     sign_in: 'signin',
                     sign_out: 'signout',
                     registration: 'signup'
                   }
        ...
      end
  end

controllers / api / v1 / session_controller.rb

  class API::V1::SessionsController < Devise::SessionsController
    respond_to :json

    private

    def respond_with(resource, _opts = {})
      render json: resource
    end

    def respond_to_on_destroy
      head :no_content
    end
  end

models / user.rb

class User < ApplicationRecord
      devise  :confirmable, :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :jwt_authenticatable, jwt_revocation_strategy: JwtBlacklist

      ...
  end

models / jwt_blacklist.rb

  class JwtBlacklist < ApplicationRecord
    include Devise::JWT::RevocationStrategies::Blacklist

    self.table_name = 'jwt_blacklist'
  end

config / инициализаторы / devise .rb

  Devise.setup do |config|

    # Setup for devise JWT token authentication
    config.jwt do |jwt|
      jwt.secret = Rails.application.secret_key_base
      jwt.dispatch_requests = [
        ['POST', %r{^*/signin$}]
      ]
      jwt.revocation_requests = [
        ['DELETE', %r{^*/signout$}]
      ]
      jwt.expiration_time = 1.day.to_i
    end

    config.navigational_formats = []

    ...

  end

spec / request / authentication_spe c .rb

  require 'rails_helper'

  describe 'POST /v1/signin', type: :request do
    let(:user) { create(:user) }
    let(:url) { '/v1/signin' }
    let(:params) do
      {
        user: {
          email: user.email,
          password: user.password
        }
      }
    end

    context 'when params are correct' do
      before do
        post url, params: params
      end

      it 'returns 200' do
        expect(response).to have_http_status(200)
      end

      it 'returns JTW token in authorization header' do
        expect(response.headers['Authorization']).to be_present
      end

      it 'returns valid JWT token' do
        decoded_token = decoded_jwt_token_from_response(response)
        expect(decoded_token.first['sub']).to be_present
      end
    end

    context 'when login params are incorrect' do
      before { post url }

      it 'returns unathorized status' do
        expect(response.status).to eq 401
      end
    end
  end

  describe 'DELETE /v1/signout', type: :request do
    let(:url) { '/v1/signout' }

    it 'returns 204, no content' do
      delete url
      expect(response).to have_http_status(204)
    end
  end

Я ожидаю, что тесты пройдут, но я получаю следующие ошибки:

Сбой теста

  Failures:

    1) POST /v1/signin when params are correct returns 200
       Failure/Error: expect(response).to have_http_status(200)
         expected the response to have status code 200 but it was 401
       # ./spec/request/authentication_spec.rb:21:in `block (3 levels) in <top (required)>'

    2) POST /v1/signin when params are correct returns JTW token in authorization header
       Failure/Error: expect(response.headers['Authorization']).to be_present
         expected `nil.present?` to return true, got false
       # ./spec/request/authentication_spec.rb:25:in `block (3 levels) in <top (required)>'

    3) POST /v1/signin when params are correct returns valid JWT token
       Failure/Error: decoded_token = decoded_jwt_token_from_response(response)

       NoMethodError:
         undefined method `decoded_jwt_token_from_response' for #<RSpec::ExampleGroups::POSTV1Signin::WhenParamsAreCorrect:0x00007fec3d3ae158>
       # ./spec/request/authentication_spec.rb:29:in `block (3 levels) in <top (required)>'

  Finished in 0.76386 seconds (files took 3.31 seconds to load)
  5 examples, 3 failures

  Failed examples:

  rspec ./spec/request/authentication_spec.rb:20 # POST /v1/signin when params are correct returns 200
  rspec ./spec/request/authentication_spec.rb:24 # POST /v1/signin when params are correct returns JTW token in authorization header
  rspec ./spec/request/authentication_spec.rb:28 # POST /v1/signin when params are correct returns valid JWT token

1 Ответ

0 голосов
/ 17 апреля 2020

Я считаю, что вам нужно использовать помощника sign_in user, прежде чем делать запрос на его авторизацию. Проверка https://github.com/heartcombo/devise, Проверка контроллера

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...