【问题标题】:How to get auth token from email and password in django rest framework?如何在 django rest 框架中从电子邮件和密码中获取身份验证令牌?
【发布时间】:2017-12-04 03:52:47
【问题描述】:

我有一个 django rest api 作为我的 android 应用程序的后端。我希望我的应用用户能够登录并注册我的应用。当用户注册或将新用户添加到用户表时,应该为该用户生成一个身份验证令牌。我在用户模型中使用以下代码执行此操作:

# This code is triggered whenever a new user has been created and saved to the database
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)

现在,当我尝试以新创建的用户身份登录时,使用令牌身份验证时,我需要做的就是在用户请求的正文中发布电子邮件和密码。我使用改造 2 这样做:

public interface UserService {
    @POST("users/api-token-auth/")
    Call<String> loginInToken(@Body LoginCredentials loginCredentials);
}

LoginCredentials 类如下所示:

public class LoginCredentials {

    private String email;
    private String password;

    public LoginCredentials() { }

    public LoginCredentials(String email, String password) {
        this.email = email;
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public String getPassword() {
        return password;
    }
}

然后,在我的应用程序中,我使用 UserService 中包含的此接口方法对 django rest api 进行以下调用:

@Override
public void loginEmailUser(LoginCredentials loginCredentials) {
    Call<String> call = userServiceApi.loginInToken(loginCredentials);
    call.enqueue(new Callback<String>() {
        @Override
        public void onResponse(Call<String> call, Response<String> response) {
            Log.d("USER_REPOSITORY", response.toString());
        }

        @Override
        public void onFailure(Call<String> call, Throwable t) {
            Log.d("USER_REPOSITORY", t.toString());
        }
    });
}

如果成功,电子邮件和密码已发送到后端,以换取相应用户的身份验证令牌,因此我应该通过发出此请求收到一个令牌。但是,当调用此端点 api-token-auth 时,会使用以下 throwable 调用 onFailure 方法:

USER_REPOSITORY: Response{protocol=http/1.0, code=400, message=Bad Request, url=http://XXX.YYY.Z.AAA:8000/users/api-token-auth/}

这是我的 django urls.py 文件,它对应于从 android 客户端调用的 url:

from django.conf.urls import url
from users import views as user_views
from rest_framework.authtoken import views as auth_views

urlpatterns = [
    url(r'^api-token-auth/', auth_views.obtain_auth_token),
    url(r'^create/', user_views.UserCreate.as_view(), name="create"),
    url(r'^$', user_views.UserList.as_view(), name="users_list"),
    url(r'^(?P<pk>[0-9]+)/$', user_views.UserDetail.as_view(), name="user_detail"),
]

django rest 文档说,使用 POST 的电子邮件和密码调用 api-token-auth url 应该会返回令牌和状态码 200。

当我似乎按照成功请求的指示进行操作时,为什么会收到错误的请求和状态代码 400?

【问题讨论】:

  • 您可以将访问令牌存储在共享首选项中,并在需要时访问它
  • 问题不在于存储它的位置,而在于我发出请求时后端没有为我提供令牌。
  • 尝试添加 map.put("grant_type", "password");作为参数
  • 如何以及在何处添加此代码?
  • 您是否在 POSTMAN 上检查过您的 API?请使用 POSTMAN 是否生成访问令牌?告诉我

标签: android python rest authentication django-rest-auth


【解决方案1】:

我正在使用 OAUth 添加 示例 LOGIN 类。我正在使用 Volley 库

public class Login extends AppCompatActivity implements View.OnClickListener {

    EditText userName, Password;
    Button login;
    public static final String LOGIN_URL = "http://192.168.100.5:84/Token";
    public static final String KEY_USERNAME = "UserName";
    public static final String KEY_PASSWORD = "Password";
    String username, password;
    String accesstoken, tokentype, expiresin, masterid, name, access, issue, expires, masterid1;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        userName = (EditText) findViewById(R.id.login_name);
        Password = (EditText) findViewById(R.id.login_password);
        userName.setHint(Html.fromHtml("<font color='#008b8b' style='italic'>Username</font>"));
        Password.setHint(Html.fromHtml("<font color='#008b8b'>Password</font>"));
        login = (Button) findViewById(R.id.login);
        login.setOnClickListener(this);
    }

    private void UserLogin() {

        username = userName.getText().toString().trim();
        password = Password.getText().toString().trim();
        StringRequest stringRequest = new StringRequest(Request.Method.POST, LOGIN_URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject jsonObject = new JSONObject(response);
                            accesstoken = jsonObject.getString("access_token");
                            tokentype = jsonObject.getString("token_type");
                            expiresin = jsonObject.getString("expires_in");
                            username = jsonObject.getString("userName");
                            masterid = jsonObject.getString("MasterID");
                            masterid = masterid.replaceAll("[^\\.0123456789]", "");

                            masterid1 = jsonObject.getString("MasterID");

                            name = jsonObject.getString("Name");
                            access = jsonObject.getString("Access");
                            issue = jsonObject.getString(".issued");
                            expires = jsonObject.getString(".expires");
                            SessionManagement session = new SessionManagement(Login.this);
                            session.createLoginSession(accesstoken, tokentype, expiresin, username, masterid, name, access, issue, expires);
                            // session.createLoginSession(masterid1);
                            openProfile();

                        } catch (JSONException e) {
                            Toast.makeText(getApplicationContext(), "Fetch failed!", Toast.LENGTH_SHORT).show();
                            e.printStackTrace();
                        }

                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // Toast.makeText(Login.this, error.toString(), Toast.LENGTH_LONG).show();
                        Toast.makeText(Login.this, "Please enter valid username and Password", Toast.LENGTH_SHORT).show();
                    }
                }) {


            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                //params.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
                return params;
            }

            @Override
            protected Map<String, String> getParams() {
                Map<String, String> map = new HashMap<String, String>();
                map.put(KEY_USERNAME, username);
                map.put(KEY_PASSWORD, password);
                //map.put("access_token", accesstoken);
                map.put("grant_type", "password");
                return map;
            }
        };
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(
                60000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));


        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(stringRequest);
    }


    private void openProfile() {
        Intent intent = new Intent(this, Home.class);
        intent.putExtra(KEY_USERNAME, username);
        startActivity(intent);


        startActivity(intent);

    }

    @Override
    public void onClick(View v) {
        UserLogin();
    }


}

这是示例。请根据您的要求进行转换

【讨论】:

    猜你喜欢
    • 2023-03-16
    • 2015-03-19
    • 2021-10-27
    • 2018-01-22
    • 2014-04-14
    • 2021-01-30
    • 2015-06-21
    • 2017-01-18
    • 1970-01-01
    相关资源
    最近更新 更多