如何基于Django REST Framework实现Android端用户登录?
嘿,很高兴看到你已经搞定了基础API,现在要做Android端的登录功能对吧?你的思路完全没问题——确实需要一个接收用户名和密码的POST API视图,不过咱们可以做得更规范,符合DRF的最佳实践,同时也适配Android端的调用需求。下面一步步给你讲怎么推进:
第一步:创建登录API视图
DRF其实提供了现成的工具帮你快速实现,当然你也可以自定义视图来满足更多需求:
用DRF内置的Token登录视图(最简单)
DRF自带的obtain_auth_token视图正好适配你的需求:它接收POST请求里的username和password参数,验证通过后返回一个用于后续身份验证的Token。你只需要在urls.py里配置路由就行:from rest_framework.authtoken.views import obtain_auth_token urlpatterns = [ # 你的其他API路由 path('api/login/', obtain_auth_token, name='api_login'), ]自定义登录视图(返回更多用户信息)
如果登录成功后想返回用户ID、昵称这类额外信息,就自己写一个视图类:from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authtoken.models import Token from django.contrib.auth import authenticate from rest_framework import status class LoginView(APIView): # 不需要身份验证就能访问这个登录接口 permission_classes = [] def post(self, request): # 从请求体里获取用户名和密码 username = request.data.get('username') password = request.data.get('password') # 验证用户名密码 user = authenticate(username=username, password=password) if user: # 获取或创建用户的Token token, created = Token.objects.get_or_create(user=user) # 返回Token和用户信息 return Response({ 'token': token.key, 'user_id': user.id, 'username': user.username }, status=status.HTTP_200_OK) # 验证失败返回错误信息 return Response({'error': '用户名或密码错误'}, status=status.HTTP_400_BAD_REQUEST)然后在
urls.py里把这个视图映射到路由:path('api/login/', LoginView.as_view(), name='api_login'),
第二步:配置Token认证
要让后续的API能通过Token验证用户身份,得在settings.py里启用Token认证:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', ], }
别忘了运行python manage.py migrate,因为DRF的Token模型需要创建对应的数据库表。
第三步:Android端的调用逻辑
Android这边可以用Retrofit或者OkHttp来发送登录请求,这里举Retrofit的例子:
- 定义请求和响应的实体类:
// 登录请求体 public class LoginRequest { private String username; private String password; // 构造方法、getter和setter public LoginRequest(String username, String password) { this.username = username; this.password = password; } } // 登录响应体 public class LoginResponse { private String token; private int user_id; private String username; // getter和setter }
- 定义Retrofit接口:
import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.POST; public interface AuthApi { @POST("api/login/") Call<LoginResponse> login(@Body LoginRequest loginRequest); }
- 发送登录请求并处理结果:
// 初始化Retrofit(建议封装成单例) Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://你的服务器地址/") .addConverterFactory(GsonConverterFactory.create()) .build(); AuthApi authApi = retrofit.create(AuthApi.class); LoginRequest loginRequest = new LoginRequest("用户名", "密码"); Call<LoginResponse> call = authApi.login(loginRequest); call.enqueue(new Callback<LoginResponse>() { @Override public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) { if (response.isSuccessful()) { LoginResponse loginResponse = response.body(); if (loginResponse != null) { // 把Token存在SharedPreferences里,后续请求用 SharedPreferences sp = getSharedPreferences("auth", MODE_PRIVATE); sp.edit().putString("token", loginResponse.getToken()).apply(); // 登录成功,跳转到主页面 } } else { // 登录失败,比如用户名密码错误,解析错误信息 try { String errorBody = response.errorBody().string(); // 处理错误提示 } catch (IOException e) { e.printStackTrace(); } } } @Override public void onFailure(Call<LoginResponse> call, Throwable t) { // 网络请求失败,提示用户 } });
- 后续请求带上Token:
在后续的API请求头里添加Authorization: Token <你的Token值>,比如用Retrofit的拦截器:
OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); SharedPreferences sp = getSharedPreferences("auth", MODE_PRIVATE); String token = sp.getString("token", ""); Request newRequest = originalRequest.newBuilder() .header("Authorization", "Token " + token) .build(); return chain.proceed(newRequest); } }) .build(); // 把这个client传给Retrofit Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://你的服务器地址/") .client(client) .addConverterFactory(GsonConverterFactory.create()) .build();
第四步:额外的优化建议
- 添加速率限制:防止暴力破解,在
settings.py里配置DRF的限流功能:REST_FRAMEWORK = { # 其他配置 'DEFAULT_THROTTLE_CLASSES': [ 'rest_framework.throttling.AnonRateThrottle', 'rest_framework.throttling.UserRateThrottle' ], 'DEFAULT_THROTTLE_RATES': { 'anon': '100/day', # 未登录用户每天最多100次请求 'user': '1000/day' # 登录用户每天最多1000次 } } - 考虑JWT认证:如果需要更安全、支持过期的认证方式,可以用
djangorestframework-simplejwt库,不过先把基础的Token认证搞懂再进阶更稳妥。 - 参数校验:在DRF视图里可以用序列化器来校验请求参数,比如确保
username和password都不为空,让接口更健壮。
内容的提问来源于stack exchange,提问作者Prashant Pandey
相关产品推荐
相关产品推荐

