我正试图在带有后端的SPA中实施适当的身份验证。
我正在寻找两个不同的前端: 1.与Ember.js的SPA 2.移动应用程序
我正在尝试设计一个同时提供服务的后端(无论是在Rails还是在Python中,还没有决定)。我希望通过Google或Facebook进行身份验证,即我不需要维护单独的用户注册,但我仍然需要维护用户,因为我希望能够合并'来自谷歌和Facebook的认证在一天结束时。出于可伸缩性的原因,我还希望后端完全无状态。此外,我更愿意在客户端尽可能多地从后端节省负载。
我的问题如下:
我将在SPA或移动应用中请求身份验证令牌。我应该将其转换为服务器端或客户端的访问令牌吗?我需要授权后端请求,我需要无状态地执行此操作。我的想法是在前端进行所有操作,并将访问令牌传递给每个后端请求,以便在服务器端进行验证,但我不确定这是否是一种有效的方法。
我希望能够合并Google和Facebook身份验证,最佳做法是什么?我计划在服务器端维护用户注册表并检查来自授权后端请求的电子邮件地址,并在电子邮件地址匹配时合并用户。什么是最佳实践,是否有任何库支持Python / Flask或Ruby或Rails?
谢谢!
答案 0 :(得分:1)
我不确定“无国籍”是什么意思。您显然需要一些数据库来存储用户的数据(否则您根本不需要后端)。所以数据库是你的状态。根据定义,HTTP协议是无状态的,因此除了在数据库中存储数据之外,您无法通过其他方式实现非常有状态。
我将在SPA或移动应用程序中请求身份验证令牌。我应该将其转换为服务器端或客户端的访问令牌吗?
如果您不需要代表用户使用Google / Facebook (并且您的措辞表明您不是),那么您就不需要将auth_token转换为server_token。
你只需要用它来调用Google / Facebook API(Ruby有两个库,所以它基本上是一行代码)并获得社交网络的用户ID和用户电子邮件。
然后在数据库中保存该ID +电子邮件,并将内部服务器令牌(只是随机字符串)提供给您的用户。您自己生成该字符串并将其提供给客户端。
如果用户从其他设备登录(即,它为您提供auth_token
,您发现该用户的电子邮件属于已注册用户之一),则您要么返回现有的内部令牌,要么生成新的并将其绑定到现有用户(取决于您优先考虑的事项 - 实现/维护简单性的高安全性)。
我希望能够合并Google和Facebook身份验证,最佳做法是什么?
Facebook 保证 如果它为您提供了用户电子邮件,那么确保 该电子邮件属于给定用户。显然,谷歌也是如此。所以你只需通过电子邮件合并它们。
您不需要一些特殊的库,因为使用您选择的语言编写代码很简单。
我按以下方式组织数据库中的所有内容:
用户表
id
email
身份验证表
user_id
email
social_uid # facebook number or google email
social_network # string, 'facebook' or 'google'
device # user agent, e.g. 'android'
ip # last login IP address
token # internal token
当用户登录时,将创建Authentication对象。如果没有此类电子邮件的用户,则创建该用户。如果有用户,则将其绑定到身份验证对象(均通过user_id
字段)。
有关访问令牌的说明
如果您计划与社交网络进行互动(除了对用户进行身份验证之外的其他方式),您应该与auth_token
交换server_token
。 server_token
是永久性的'} (好吧,种类)用于访问社交网络API的授权令牌,而auth_token
的生命周期非常有限(如果您没有获得server_token
,某些API调用可能会受到限制。)< / p>
仍然,server_token
可能会过期(或者用户可以回忆他们对您的应用程序的访问权限),因此您应该提前计划检测该情况并在需要时重新获取令牌/授权。
构建Rails应用程序时的关键点
在Rails中,为了创建表,您需要编写migrations:
gem install rails
rails new my_project
cd my_project
rails generate migration create_users
rails generate migration create_authentications
这将生成项目文件夹结构和两个迁移文件,您需要填写这些文件:
# db/migrate/xxx_create_users.rb
def change
create_table :users do |t|
t.string :email
end
end
# db/migrate/xxx_create_authentications.rb
def change
create_table :authentications do |t|
t.integer :user_id
t.index :user_id
t.string :social_uid
# etc., all other fields
# ...
end
end
然后你生成&#39; models&#39;处理与数据库相关的操作:
# app/models/user.rb
class User < ActiveRecord::Base
has_many :authentications
end
# app/models/authentication.rb
class Authentication < ActiveRecord::Base
belongs_to :user
before_create :set_token
after_commit :create_user_if_needed
private
def set_token
self.token = SecureRandom.urlsafe_base64(20)
end
def create_user_if_needed
unless self.user.present?
self.user.create(email: self.email)
end
end
end
并撰写&#39; controller&#39;使用单个方法处理来自用户的请求:
# app/controllers/login_controller.rb
class LoginController < ActionController
# Login via Facebook method
def facebook
token = params.require(:auth_token)
# we will use Koala gem
profile = Koala::Facebook::API.new(token).get_object('me', fields: 'email')
# user is created automatically by model
authentication = Authentication.where(social_network: 'facebook', social_uid: profile['id'], email: profile['email']).first_or_create
authentication.update(...) # set ip and device
render json: {token: authentication.token}
end
# This one you'll have to write yourself as an exercise :)
def google
end
end
当然,您需要为行动设置routes:
# config/routes.rb
post "login/:action", controller: 'login'
将Koala(或其他任何你用来管理已经存在优秀Ruby包的外部API)添加到Gemfile:
# Gemfile
gem 'koala'
然后在您的终端运行中:
bundle install
rails server
您的应用已启动并正在运行。好吧,您需要先设置您的Facebook和Google应用程序,获取开发人员密钥,并授权localhost
接受auth_tokens
。
基本上就是这样。