Отправляется электронное письмо с подтверждением, как запретить пользователям вход в систему, если они не подтверждают почту? - PullRequest
1 голос
/ 30 мая 2019

Я использую устройство. До того, как я смог войти без подтверждения по электронной почте. Затем мне пришлось настроить подтверждение по электронной почте для моего приложения. Поэтому я добавил подтверждаемый файл user.rb и внес изменения при разработке пользовательской миграции. Также я внес изменения в файл devise.rb. Также я настроил почтовую программу как smtp в файле config / environment / development.rb.

Я думаю, что установка правильна для почтовой программы, но проблема в том, что: Когда пользователь регистрируется как новый пользователь, почта с токеном подтверждения отправляется этому пользователю. Но даже не нажимая эту ссылку, пользователь может войти в систему. Какая польза от установки для почтовой программы, если пользователь может войти без токена подтверждения? Как запретить пользователям входить в систему, если они не проверяют токен подтверждения почты?
Я устал делать настраиваемый подтверждающий контроллер, но результат тот же.

application_controller.rb

# frozen_string_literal: true

# Router entry point
require 'json_web_token'
class ApplicationController < ActionController::Base
    before_action :configure_permitted_parameters, if: :devise_controller?
    before_action :make_action_mailer_use_request_host_and_protocol
    # before_action :authenticate_user!, :set_mailer_host
    protect_from_forgery with: :exception

    respond_to :html, :json

    def index
        render template: 'application'
    end

    def not_found
        render json: { error: 'not_found' }
    end

    def authorize_request
        header = request.headers['Authorization']
        header = header.split(' ').last if header
        begin
        @decoded = JsonWebToken.decode(header)
        @current_user = User.find(@decoded[:user_id])
        rescue ActiveRecord::RecordNotFound => e
        render json: { errors: e.message }, status: :unauthorized
        rescue JWT::DecodeError => e
        render json: { errors: e.message }, status: :unauthorized
        end
    end

    protected

    def current_user
        @current_user ||= User.find_by(id: session[:user_id])
    end

    def signed_in?
        !!current_user
    end
    helper_method :current_user, :signed_in?

    def current_user=(user)
        session[:user_id] = user&.id
        @current_user = user
    end

    def configure_permitted_parameters
        update_attrs = [:password, :password_confirmation, :current_password]
        devise_parameter_sanitizer.permit :account_update, keys: update_attrs
        devise_parameter_sanitizer.permit(:login, keys: [ :email, :password ])
    end

    private

    def make_action_mailer_use_request_host_and_protocol
        ActionMailer::Base.default_url_options[:protocol] = request.protocol
        ActionMailer::Base.default_url_options[:host] = request.host_with_port
    end 
end

authorization_controller.rb

module Api
    module V1
        class AuthenticationController < ApplicationController
            skip_before_action :verify_authenticity_token
            before_action :authorize_request, except: :login

            # POST /auth/login
            def login
                @user = User.find_by_email(params[:email])
                if @user&.valid_password?(params[:password])
                token = JsonWebToken.encode(user_id: @user.id)
                time = Time.now + 24.hours.to_i
                render json: { token: token, exp: time.strftime("%m-%d-%Y %H:%M"),
                                username: @user.username, user_id: @user.id }, status: :ok
                else
                render json: { error: 'unauthorized' }, status: :unauthorized
                end
            end

            private

            def login_params
                params.permit(:email, :password)
            end
        end
    end
end

users_controller.rb

module Api
    module V1
        class UsersController < ApplicationController
            skip_before_action :verify_authenticity_token

            before_action :authorize_request, except: :create

            # GET /users
            def index
                @users = User.all
                render json: @users, status: :ok
            end

            def create
                # render plain: params.inspect
                @user = User.new(user_params)
                # render plain: user_params.insp
                if @user.save
                    render json: @user, status: :created
                else
                    render json: { errors: @user.errors.full_messages },
                        status: :unprocessable_entity
                end
            end

            def update
                user = User.find(params[:id])
                if user.update(user_params)
                render json: user, status: :created
                else
                render json: { errors: user.errors.full_messages },
                        status: :unprocessable_entity
                end
            end

            def show
                user = User.find(params[:id])
                if !user.nil?
                    render json: user, status: :ok
                else
                    render json: {errors: user.errors.full_messages}, status: :unprocessable_entity
                end
            end

            def destroy
                user = User.find(params[:id])
                if user.destroy
                    render json: {success: "deleted successfully"}, status: :ok
                else
                    render json: {errors: user.errors.full_messages}, status: :not_acceptable
                end
            end

            private

            def find_user
                @user = User.find_by_username!(params[:_username])
                rescue ActiveRecord::RecordNotFound
                render json: { errors: 'User not found' }, status: :not_found
            end

            def user_params
                params.permit(
                    :first_name, :last_name, :username, :email, :password, :password_confirmation
                )
            end
        end
    end
end

registrations_controller.rb

class RegistrationsController < Devise::RegistrationsController
    skip_before_action :require_no_authentication
    def update_resource(resource, params)
        if resource.encrypted_password.blank?
            resource.email = params[:email] if params[:email]
            if !params[:password].blank? && params[:password] == params[:password_confirmation]
                resource.password = params[:password]
                resource.save
            end
            if resource.valid?
            resource.update_without_password(params)
            end
        else
            resource.update_with_password(params)
        end
    end
end

user.rb

class User < ApplicationRecord
    # has_secure_password
    # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable and :omniauthable
    devise :database_authenticatable, :registerable,
        :recoverable, :rememberable, :trackable, :validatable,
        :confirmable, :omniauthable, password_length: 8..36
    has_many :identities
    has_one :testimonials
    has_many :questions
    has_many :answers


    def facebook
        identities.where(provider: 'facebook').first
    end

    def facebook_client
        @facebook_client ||= Facebook.client(access_token: facebook.accesstoken)
    end

    def twitter
        identities.where(provider: 'twitter').first
    end

    def twitter_client
        @twitter_client ||= Twitter.client(access_token: twitter.accesstoken)
    end

    def google_oauth2
        identities.where(provider: 'google_oauth2').first
    end

    def google_oauth2_client
        unless @google_oauth2_client
        @google_oauth2_client = Google::APIClient.new(application_name: '',
                                                        application_version: '')
        @google_oauth2_client.authorization.update_token!(access_token: google_oauth2.accesstoken,
                                                            refresh_token: google_oauth2.refreshtoken)
        end
        @google_oauth2_client
    end

    #validation for users
    validates :username, presence: true, uniqueness: {case_sensitive: false}

    # validates_format_of :username, with: /^[a-zA-Z0-9_\.]*$/, :multiline => true
    validates :email, presence: true, uniqueness: {case_senstive: false}
    PASSWORD_FORMAT = /\A
        (?=.{8,})          # Must contain 8 or more characters
        (?=.*\d)           # Must contain a digit
        (?=.*[a-z])        # Must contain a lower case character
        (?=.*[A-Z])        # Must contain an upper case character
        (?=.*[[:^alnum:]]) # Must contain a symbol
        /x

    validates :password,
        presence: true,
        # length: { in: Devise.password_length },
        format: { with: PASSWORD_FORMAT, message: 'must contain 8 Characters with at least One Lowercase, One Uppercase, One Number and One Special Character' },
        confirmation: true,
        on: :create

        validates :password_confirmation,
        presence: true

    validates :password,
        # allow_nil: true,
        # length: { in: Devise.password_length },
        format: { with: PASSWORD_FORMAT, message: 'must contain 8 Characters with at least one Uppercase, One Number and One Special Character' },
        confirmation: true,
        on: :update

end

1 Ответ

1 голос
/ 30 мая 2019

Посмотрите на ваш инициализатор устройства, вам нужно установить allow_unconfirmed_access_for в 0 (на самом деле, по умолчанию он должен быть равен нулю). Согласно разработать документацию :

#   * +allow_unconfirmed_access_for+: the time you want to allow the user to access their account
#     before confirming it. After this period, the user access is denied. You can
#     use this to let your user access some features of your application without
#     confirming the account, but blocking it after a certain period (ie 7 days).
#     By default allow_unconfirmed_access_for is zero, it means users always have to confirm to sign in.

Devise использует этот метод для проверки неподтвержденного доступа.

Не могли бы вы также опубликовать результаты этих методов:

  • User.find(id_of_user_that_was_just_created).confirmation_required?
  • User.find(id_of_user_that_was_just_created).confirmed?
  • User.find(id_of_user_that_was_just_created).confirmation_period_valid?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...