You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 7 + Devise加密邮箱字段报错问题求助

问题描述

使用Rails 7 + Devise gem,尝试对Devise生成的email字段进行加密,已执行rails db:encryption:init并配置凭证。

User模型代码:

class User < ApplicationRecord
  
  encrypts :email, deterministic: true, downcase: true
  validates :email, presence: true
  
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :confirmable

end

遇到的问题:

  1. 访问登录、注册路径时触发错误:

    ActiveRecord::Encryption::Errors::Decryption in Devise::Sessions#new
    ActiveRecord::Encryption::Errors::Decryption in Devise::Registrations#new
    

    错误指向视图中的<%= f.input :email,代码行。

  2. Rails控制台创建新用户时出现:

    unexpected token at '' (JSON::ParserError) 
    ActiveRecord::Encryption::Errors::Encoding (ActiveRecord::Encryption::Errors::Encoding)
    ActiveRecord::Encryption::Errors::Decryption (ActiveRecord::Encryption::Errors::Decryption)
    
解决方案

1. 验证加密凭证完整性

使用rails credentials:edit打开凭证文件,确认active_record_encryption下的三个密钥均存在且非空:

active_record_encryption:
  primary_key: [你的主密钥]
  deterministic_key: [你的确定性密钥]
  key_derivation_salt: [你的密钥派生盐]

这三个密钥由rails db:encryption:init自动生成,缺一不可,缺失或空值会直接导致编码/解密错误。

2. 处理现有未加密数据(适用于已有用户记录的项目)

如果数据库中存在未加密的email记录,直接添加encrypts配置会触发解密错误,需先批量加密现有数据:

  • 暂时注释模型中的encrypts :email语句
  • 启动Rails控制台执行加密:
    User.find_each do |user|
      encrypted_email = User.encryptor.encrypt(user.email, deterministic: true, downcase: true)
      user.update_column(:email, encrypted_email)
    end
    
  • 恢复encrypts :email语句,重启服务器

3. 调整数据库字段长度

加密后的字符串会比原始邮箱长,需确保email字段有足够存储空间:

  • 生成迁移文件修改字段类型:
    # db/migrate/[时间戳]_change_email_field_type.rb
    class ChangeEmailFieldType < ActiveRecord::Migration[7.0]
      def change
        change_column :users, :email, :text
      end
    end
    
  • 执行迁移:rails db:migrate

4. 排查控制台创建错误

控制台的JSON解析错误通常由凭证文件格式问题或Ruby版本不兼容导致:

  • 检查config/credentials.yml.enc的YAML格式,确保没有多余空格、引号或语法错误
  • 确认Ruby版本为2.7及以上(Rails 7官方推荐版本)
兼容性说明

Rails 7的ActiveRecord Encryption与Devise完全兼容。由于登录、密码找回等功能需要基于email字段查询,使用deterministic: true的加密配置正好满足这一需求(确定性加密支持等值查询),只要正确配置密钥和处理数据,就能正常配合Devise使用。

内容的提问来源于stack exchange,提问作者Mr McDonald

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:15:34