【问题标题】:Authentication: JWT in RoR and android身份验证:RoR 和 android 中的 JWT
【发布时间】:2017-01-11 08:18:18
【问题描述】:

红宝石 2.2.4 导轨 5.0.0.1 改造:1.9.0' 奥托:1.3.8'

大家好,

我只是编程的初学者,我的任务是使用 Android Studio 创建一个 Android 应用程序,您可以在其中以用户身份登录和注销。所以 我使用 Json Web Token (JWT) 在 RoR 5 API 中编写了基于令牌的身份验证。本教程帮助了我:http://tutorials.pluralsight.com/ruby-ruby-on-rails/token-based-authentication-with-ruby-on-rails-5-api)。将正确的凭据放入 curl 后,我终于收到了令牌:{"auth_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0NjA2NTgxODZ9.xsSwcPC22IR71OBv6bU_OGCSyfE89DvEzWfDU0iybMA"}

现在工作正常后,我尝试在 android studio 中实现登录功能,它应该与我的 RoR 服务器交互。 我严格遵循了一个教程(https://www.sitepoint.com/retrofit-a-simple-http-client-for-android-and-java/),它使用 Retrofit 与 php 服务器进行身份验证。但是我想为我的 RoR 服务器实现这个。尽管如此,我还是尝试了这段代码。我很高兴,该程序可以与我在 Rails 服务器上的 ruby​​ 进行通信。如果我使用正确的凭据登录 android 应用程序,我会在控制台上看到它会被接受。

但是我不知道如何在 android 上收到一条消息,即登录成功以及带有用户名的欢迎消息。正如我所说,我在 RoR 中使用 JWT,它会返回一个长令牌。改造是否有可能解释这个令牌?还是我需要为 android 安装 JSON Web Token?以下是 ruby​​ on rails 中的部分代码:

app/commands/authenticate_user.rb

class AuthenticateUser
  prepend SimpleCommand

  def initialize(email, password)
    @email = email
    @password = password
  end

  def call
JsonWebToken.encode(user_id: user.id) if user
  end

  private

  attr_accessor :email, :password

  def user
    user = User.find_by_email(email)
    return user if user && user.authenticate(password)

    errors.add :user_authentication, 'invalid credentials'
    nil
  end
end

lib/json_web_token.rb

class JsonWebToken
  class << self
    def encode(payload, exp = 24.hours.from_now)
      payload[:exp] = exp.to_i
      JWT.encode(payload, Rails.application.secrets.secret_key_base)
    end

    def decode(token)
      body = JWT.decode(token, Rails.application.secrets.secret_key_base)[0]
      HashWithIndifferentAccess.new body
    rescue
      nil
    end
  end
end

这是我的android应用程序的一部分,代码来自我遵循的教程:

public class Communicator {
    private static  final String TAG = "Communicator";
    private static final String SERVER_URL = "http://127.0.0.1/retrofit";

    public void loginPost(String username, String password){
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(SERVER_URL)
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .build();
        Interface communicatorInterface = restAdapter.create(Interface.class);
        Callback<ServerResponse> callback = new Callback<ServerResponse>() {
            @Override
            public void success(ServerResponse serverResponse, Response response2) {
                if(serverResponse.getResponseCode() == 0){
                    BusProvider.getInstance().post(produceServerEvent(serverResponse));
                }else{
                    BusProvider.getInstance().post(produceErrorEvent(serverResponse.getResponseCode(), serverResponse.getMessage()));
                }

            }

            @Override
            public void failure(RetrofitError error) {
                if(error != null ){
                    Log.e(TAG, error.getMessage());
                    error.printStackTrace();
                }
                BusProvider.getInstance().post(produceErrorEvent(-200,error.getMessage()));
            }
        };
        communicatorInterface.postData("login", username, password, callback);
    }

    public void loginGet(String username, String password){
        RestAdapter restAdapter = new RestAdapter.Builder()
                .setEndpoint(SERVER_URL)
                .setLogLevel(RestAdapter.LogLevel.FULL)
                .build();
        Interface communicatorInterface = restAdapter.create(Interface.class);
        Callback<ServerResponse> callback = new Callback<ServerResponse>() {
            @Override
            public void success(ServerResponse serverResponse, Response response2) {
                if(serverResponse.getResponseCode() == 0){
                    BusProvider.getInstance().post(produceServerEvent(serverResponse));
                }else{
                    BusProvider.getInstance().post(produceErrorEvent(serverResponse.getResponseCode(), serverResponse.getMessage()));
                }
            }

            @Override
            public void failure(RetrofitError error) {
                if(error != null ){
                    Log.e(TAG, error.getMessage());
                    error.printStackTrace();
                }
                BusProvider.getInstance().post(produceErrorEvent(-200,error.getMessage()));
            }
        };
        communicatorInterface.getData("login", username, password, callback);
    }
}

这是 android 教程中的 PHP 脚本。也许我需要把它转移到红宝石中

<?php

    //Post Method here
    if(isset($_POST['method']) == 'login'){
        $username = $_POST['username'];
        $password = $_POST['password'];

        if($username == "admin" && $password == "admin"){
            $response = array('returned_username' => "-admin-",
                              'returned_password' => "-admin-",
                              'message' => "Your credentials are so weak [USING_POST]!",
                              'response_code' => "1");
               echo json_encode($response);

        }else{
            $response = array('response_code' => "-1",
                              'message' => "invalid username or password");
               echo json_encode($response);
        }
    }

php 中的 json 编码包括一个数组(用户名、密码、消息、响应码)。如何在 ruby​​ on rails 上包含与 JWT 相同的数组?任何想法?以及我如何在 android 上收到登录成功的消息

【问题讨论】:

    标签: android ruby-on-rails retrofit jwt


    【解决方案1】:

    有一种方法可以检索令牌值,首先将这些行添加到您的 ServerResponse.java 文件中:

    @SerializedName("token")
    private String token;
    
    String token
    
    this.token = token;
    
    public String getToken() { return token; }
    
    public void setToken(String token) {
        this.token = token;
    }
    

    根据已经存在的内容,然后转到主要活动并将令牌存储在变量中,例如:

    String auth_token = serverEvent.getServerResponse().getToken()
    

    接下来,您可以将其设为 private final 并在您的整个项目中使用它。

    希望对你有帮助!

    【讨论】:

      【解决方案2】:

      在JsonWebToken.encode(user_id: user.id) if user 行中,您传递了一个带有user_id 键的哈希值。您可以扩展此行以包含其他属性,有点像 JsonWebToken.encode(user_id: user.id, name: user.name) if user.

      然后,您需要在您的 android 应用程序中包含一个 JWT 库并解码服务器响应(从 Retrofit 获得),您将能够访问您编码的属性。

      【讨论】:

      • 非常感谢您的建议。我听从了您的建议并实现了 JWT 库,现在可以对令牌进行编码。但我不知道如何获得令牌。令牌仅出现在机器人控制台:com.example.programmingknowledge.login d /改造:{ “的auth_token”: “eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJuYW1lIjpudWxsLCJlbWFpbCI6ImV4YW1wbGVAbWFpbC5jb20iLCJleHAiOjE0NzMwMzU1MTF9.bhJABvEgtRISZVJ0DejjEtrGJyXzNV6PO0YGQ71xHRc”} 跨度>
      • 如何在我的安卓应用中获取完整的令牌?
      猜你喜欢
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      • 2019-04-15
      • 2020-07-23
      • 2019-02-14
      • 1970-01-01
      • 2023-01-22
      • 2018-12-06
      相关资源
      最近更新 更多