1

我正在开发一个我想使用 OmniAuth 的 Sinatra 应用程序。到目前为止,对于网络应用程序,我有类似的东西:

http://codebiff.com/omniauth-with-sinatra

我希望网络应用程序可以通过使用 API 的 Android 手机使用,通过令牌进行身份验证。API 的开发似乎在这里很好地涵盖了:

Sinatra - API - 身份验证

不清楚的是现在我可能会安排登录程序。大概是这样的:

  1. 用户通过 Android 设备上的应用内按钮选择要使用的服务,例如 Twitter、FaceBook 等。
  2. Android 应用程序打开一个 web 视图以登录到 Web 应用程序。
  3. 令牌以某种方式创建,存储在 Web 应用程序的数据库中,然后返回给 Android 应用程序,以便可以存储它并用于后续的 API 请求。

我不太清楚如何管理第 3 点 - 有人有什么建议吗?

4

1 回答 1

5

由于似乎没有人有任何建议,这就是我到目前为止提出的建议。不过,我认为这不是很好。

我已向用户模型添加了一个 API 密钥,该密钥是在用户首次通过身份验证时创建的:

class User
  include DataMapper::Resource
  property :id,         Serial, :key => true
  property :uid,        String
  property :name,       String
  property :nickname,   String
  property :created_at, DateTime
  property :api_key,    String, :key => true
end

....


get '/auth/:name/callback' do
  auth = request.env["omniauth.auth"]
  user = User.first_or_create({ :uid => auth["uid"]}, 
                              { :uid => auth["uid"], 
                                :nickname => auth["info"]["nickname"], 
                                :name => auth["info"]["name"],
                                :api_key => SecureRandom.hex(20),
                                :created_at => Time.now })
  session[:user_id] = user.id
  session[:api_key] = user.api_key
  flash[:info] = "Welcome, #{user.name}"
  redirect "/success/#{user.id}/#{user.api_key}"
end

如果授权有效,则将 api_key 提供给 Android 应用程序,该应用程序可能会将其存储在设备上的某个位置:

get '/success/:id/:api_key', :check => :valid_key? do
  user = User.get(params[:id],params[:api_key])
  if user.api_key == params[:api_key]
    {'api_key' => user.api_key}.to_json 
  else
    error 401
  end
end

所有 API 调用都受到保护,如我原始帖子中的链接所示:

register do
  def check (name)
    condition do
      error 401 unless send(name) == true
    end
  end
end

helpers do
  def valid_key?
    user = User.first(:api_key => params[:api_key])
    if !user.nil?
      return true
    end
    return false
  end
end

对于公共用途,我只允许 SSL 连接到服务器。欢迎任何改进建议。

于 2012-04-11T15:16:57.893 回答