接入Google OmniAuth的Rails API如何从access_token定义user_id
解决方案
你完全可以保留之前用SecureRandom.hex生成用户唯一内部user_id的逻辑,不需要和Google返回的ID绑定作为主键,只需要做一层关联映射即可,具体步骤如下:
- 第一步:给你的User表新增
provider和uid两个字段,分别存储第三方登录的来源(当前场景固定为google_oauth2)和Google返回的用户唯一标识,给这两个字段加联合唯一索引,避免同一个Google账号重复创建用户。 - 第二步:用户用Google登录拿到access_token后,先调用Google的用户信息校验接口拉取用户的
sub字段(这个就是Google侧对应用户的永久唯一ID),拿这个sub值去User表的uid字段匹配,同时限定provider为google_oauth2。- 如果匹配到已有用户,直接返回该用户你之前用
SecureRandom.hex生成的内部user_id即可 - 如果没匹配到,就新创建一个用户,用
SecureRandom.hex生成新的内部user_id,同时把provider设为google_oauth2、uid设为拉取到的sub值,存库之后返回新生成的user_id
- 如果匹配到已有用户,直接返回该用户你之前用
你之前担心直接用Google返回的ID作为user_id有风险是完全合理的,内部ID和第三方ID解耦之后,后续如果要新增其他登录方式、或者用户需要绑定多个登录渠道,都不需要修改内部user_id的生成逻辑,不会影响现有业务关联的用户数据。
你可以参考下面的Rails示例代码实现:
def google_callback access_token = params[:access_token] # 用access_token校验并拉取Google用户信息 google_user_info = Google::Auth::IDTokens.verify_oidc(access_token, aud: ENV['GOOGLE_CLIENT_ID']) uid = google_user_info['sub'] user = User.find_or_initialize_by(provider: 'google_oauth2', uid: uid) if user.new_record? user.id = SecureRandom.hex(16) # 沿用你原有user_id生成逻辑 user.email = google_user_info['email'] user.name = google_user_info['name'] user.save! end render json: { user_id: user.id }, status: :ok end
内容的提问来源于stack exchange,提问作者Paulina Markowska
相关产品推荐
相关产品推荐

