到目前为止,我的网站一直使用Rails直接生成的fullstack视图,对于linkedin身份验证,我使用redirect_uri路由到Devise::OmniauthCallbacksController
来处理逻辑。
GET https://www.linkedin.com/oauth/v2/authorization?redirect_uri=my_devise_omniauth_callback_url
我想知道如何将其迁移到独立的React前端+独立的Rails服务器。 React应用程序应该"产生"一个用于授权的linkedin弹出窗口,等待所有授权过程完成后再关闭自己并继续在主窗口上注册。
我已经通过Linkedin OAuth guide,我看到从批准连接到获取用户信息的方式很长。我很高兴Devise / Omniauth为我服务器方面完成了大部分工作,我宁愿保持这种方式,而不是在前端编写逻辑。
(顺便说一下,假设Linkedin OAuth流程类似于the Google one mentionned in this answer是否安全?)
我不确定这是否可以按照我在React应用程序上看到的方式完成(特别是在LUN弹出窗口和主反应视图之间的数据通信)。另外根据我的理解,rails中的omniauth gem
期望从OAuth提供者接收一次性令牌,然后再次向提供者查询两次(第一次交换访问令牌,第二次获取用户信息)。以下是否有效?
client.example.com
api.example.com
api.example.com
,它获取访问代码并从Linkedin检索用户数据。它返回浏览器identity_id
,可用于注册identity_id
实际上已返回弹出窗口,并转回主React应用程序(如何?)答案 0 :(得分:2)
我有同样的问题,我找到了一个hacky但有趣的解决方案:-)
(我使用devise
和omniauth-linkedin
宝石中的所有OAuth逻辑。)
在我的应用程序中,您可以开始填写表单,然后在保存之前需要登录。我需要一种方法来记录用户而不会丢失表单数据而无需重新加载页面。
当用户访问该页面时,他会获得一个独特的uuid来识别他。这个uuid用于启动websocket连接,因此我可以稍后将数据直接推送到此选项卡。
我使用javascript window.open()
在新标签页中打开LinkedIn OAuth,因此我可以使用window.close()
关闭此标签。
您可以将其他参数传递给OAuth身份验证,我传递了唯一的uuid,以便在身份验证成功时我可以恢复它并使用此uuid我可以通过websocket发送消息通知第一个选项卡(在我的应用程序中发送用户信息以使用当前用户更新状态。
身份验证后,我将用户重定向到仅包含window.close()
的页面。
您需要有效的Omniauth / Devise身份验证工作。
omniauth_callback_controller.rb
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def linkedin
user = User.connect_to_linkedin(request.env["omniauth.auth"], current_user)
guest_guid = request.env["omniauth.params"]["guestGuid"]
if user.persisted?
ActionCable.server.broadcast("guest:#{guest_guid}", { user: UserSerializer.new(user).to_h })
sign_in(user)
redirect_to landing_home_index_path
end
end
end
user.rb
def self.connect_to_linkedin(auth, signed_in_resource = nil)
user = User.where(provider: auth.provider, linkedin_uid: auth.uid).first
if user
return user
else
registered_user = User.where(email: auth.info.email).first
if registered_user
return registered_user
else
user = User.create(lastname: auth.info.last_name, firstname: auth.info.first_name,
provider: auth.provider, linkedin_uid: auth.uid, email: auth.info.email,
linkedin_token: auth.credentials.token, linkedin_secret: auth.credentials.secret,
linkedin_picture: auth.extra.raw_info.pictureUrl, password: Devise.friendly_token[0, 20])
end
end
end
的routes.rb
devise_for :users, controllers: {
omniauth_callbacks: "omniauth_callbacks",
sessions: "users/sessions"
}
现在,如果您访问/users/auth/linkedin
,您将能够使用LinkedIn OAuth登录/创建用户。
create_job_offer_channel.rb
class CreateJobOfferChannel < ApplicationCable::Channel
def subscribed
stream_from "guest:#{params[:guest]}"
end
def unsubscribed
end
def receive(data)
ActionCable.server.broadcast("guest:#{params[:guest]}", data)
end
end
create_job_offer.js.coffee
class window.CreateJobOffer
constructor: (params) ->
self = @
@channel = App.cable.subscriptions.create {
channel: "CreateJobOfferChannel", guest: params["guest"]
}, self
@onReceive = params["onReceive"] || null
received: (data) =>
@onReceive(data) if @onReceive
链接到LinkedIn OAuth(使用设计和omniauth)
<div className="btn-linked-in">
<i className="fa fa-linkedin-square"></i>
<span onClick={() => open(`/users/auth/linkedin?guestGuid=${guestGuid}`)}>
Login with LinkedIn
</span>
</div>
希望这有帮助:)