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

求助:使用Devise实现Google OAuth后移动端登录重定向至桌面视口

解决Devise Google OAuth移动端登录后跳转桌面视图问题

问题描述

使用Devise实现Google OAuth登录功能时,在移动端浏览器完成认证后,会被重定向至桌面版视图。当前使用的回调控制器代码如下:

class Reactors::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def google_oauth2
    reactor = Reactor.from_google(google_user_details)

    if reactor.present?
      sign_out_all_scopes
      flash[:success] = t "devise.omniauth_callbacks.success", kind: "Google"
      sign_in_and_redirect reactor, event: :authentication
    else
      flash[:alert] = t "devise.omniauth_callbacks.failure", kind: "Google", reason: "#{auth.info.email} is not authorized."
      redirect_to new_reactor_session_path
    end
  end

  protected

  def after_omniauth_failure_path_for(_scope)
    new_reactor_session_path
  end

  def after_sign_in_path_for(resource_or_scope)
    stored_location_for(resource_or_scope) || root_path
  end
end

解决方案

1. 识别移动端请求

首先需要在Rails中识别移动端请求,可通过两种方式实现:

  • 使用mobile-fu gem:
    1. 在Gemfile添加:gem 'mobile-fu'
    2. 执行bundle install
    3. 在ApplicationController中引入:include MobileFu
  • 自定义User-Agent判断:
    直接在控制器中添加判断方法:
    def mobile_request?
      request.user_agent =~ /Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/
    end
    

2. 修改登录后重定向逻辑

修改after_sign_in_path_for方法,根据设备类型返回对应页面路径:

def after_sign_in_path_for(resource_or_scope)
  # 优先使用用户原本的跳转目标
  stored_path = stored_location_for(resource_or_scope)
  return stored_path if stored_path.present?

  # 根据设备类型跳转对应首页
  if request.mobile? # 或使用自定义的mobile_request?方法
    mobile_root_path # 替换为你的移动端首页路由助手
  else
    root_path
  end
end

3. 检查OAuth回调URL配置

登录Google Cloud Console,确认OAuth 2.0回调URL包含移动端适配的地址(若移动端使用独立域名):

  • 桌面端示例:https://your-domain.com/auth/google_oauth2/callback
  • 移动端示例:https://m.your-domain.com/auth/google_oauth2/callback

4. 强制响应格式(可选)

若重定向时格式被自动切换为桌面版,可在回调方法中指定响应格式:

def google_oauth2
  reactor = Reactor.from_google(google_user_details)

  if reactor.present?
    sign_out_all_scopes
    flash[:success] = t "devise.omniauth_callbacks.success", kind: "Google"
    # 根据设备类型设置响应格式
    redirect_path = if request.mobile?
                      sign_in_and_redirect(reactor, event: :authentication, format: :mobile)
                    else
                      sign_in_and_redirect(reactor, event: :authentication)
                    end
  else
    flash[:alert] = t "devise.omniauth_callbacks.failure", kind: "Google", reason: "#{auth.info.email} is not authorized."
    redirect_to new_reactor_session_path
  end
end

内容的提问来源于stack exchange,提问作者Bikash Pandey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:52:37