首页
学习
活动
专区
圈层
工具
发布

从java/android获取web api/asp token

Java/Android 获取 Web API (ASP.NET) Token 的完整指南

基础概念

什么是 Token

Token 是一种用于身份验证和授权的凭证,通常由服务器颁发,客户端在后续请求中携带以证明身份。在 Web API 中常用的是 JWT (JSON Web Token)。

认证流程

  1. 客户端发送凭据(用户名/密码)到认证端点
  2. 服务器验证凭据并返回 Token
  3. 客户端在后续请求的 Header 中携带 Token
  4. 服务器验证 Token 并处理请求

实现方式

1. 使用 Retrofit (推荐)

代码语言:txt
复制
// 定义认证接口
public interface AuthService {
    @POST("api/auth/login")
    Call<AuthResponse> login(@Body LoginRequest request);
}

// 请求和响应模型
public class LoginRequest {
    private String username;
    private String password;
    
    // getters and setters
}

public class AuthResponse {
    private String token;
    private String refreshToken;
    private long expiresIn;
    
    // getters and setters
}

// 实际调用
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://your-api.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build();

AuthService authService = retrofit.create(AuthService.class);

LoginRequest request = new LoginRequest("username", "password");
Call<AuthResponse> call = authService.login(request);

call.enqueue(new Callback<AuthResponse>() {
    @Override
    public void onResponse(Call<AuthResponse> call, Response<AuthResponse> response) {
        if (response.isSuccessful()) {
            String token = response.body().getToken();
            // 存储token用于后续请求
            SharedPreferences prefs = getSharedPreferences("AppPrefs", MODE_PRIVATE);
            prefs.edit().putString("auth_token", token).apply();
        }
    }

    @Override
    public void onFailure(Call<AuthResponse> call, Throwable t) {
        // 处理错误
    }
});

2. 使用 HttpURLConnection

代码语言:txt
复制
public class AuthHelper {
    public static String getAuthToken(String username, String password) throws IOException {
        URL url = new URL("https://your-api.com/api/auth/login");
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setDoOutput(true);

        String jsonInputString = "{\"username\": \"" + username + "\", \"password\": \"" + password + "\"}";

        try(OutputStream os = conn.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);           
        }

        try(BufferedReader br = new BufferedReader(
            new InputStreamReader(conn.getInputStream(), "utf-8"))) {
            StringBuilder response = new StringBuilder();
            String responseLine;
            while ((responseLine = br.readLine()) != null) {
                response.append(responseLine.trim());
            }
            
            JSONObject jsonObject = new JSONObject(response.toString());
            return jsonObject.getString("token");
        }
    }
}

Token 存储与管理

安全存储

  • 使用 Android 的 EncryptedSharedPreferences 存储 Token
  • 或使用 AndroidKeyStore 加密存储
代码语言:txt
复制
// 使用 EncryptedSharedPreferences 存储 token
String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC);

SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(
    "secret_shared_prefs",
    masterKeyAlias,
    context,
    EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
    EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);

sharedPreferences.edit().putString("auth_token", token).apply();

Token 刷新

实现 Token 刷新机制以处理过期问题:

代码语言:txt
复制
public class TokenAuthenticator implements Authenticator {
    @Override
    public Request authenticate(Route route, Response response) throws IOException {
        // 获取当前token
        SharedPreferences prefs = getSharedPreferences("AppPrefs", MODE_PRIVATE);
        String refreshToken = prefs.getString("refresh_token", null);
        
        if (refreshToken == null) {
            return null; // 无法刷新,需要重新登录
        }
        
        // 使用refresh token获取新token
        AuthService authService = retrofit.create(AuthService.class);
        Call<AuthResponse> call = authService.refreshToken(new RefreshRequest(refreshToken));
        retrofit2.Response<AuthResponse> res = call.execute();
        
        if (res.isSuccessful()) {
            String newToken = res.body().getToken();
            prefs.edit().putString("auth_token", newToken).apply();
            
            return response.request().newBuilder()
                .header("Authorization", "Bearer " + newToken)
                .build();
        }
        
        return null;
    }
}

常见问题与解决方案

1. 401 Unauthorized 错误

原因

  • Token 过期
  • Token 无效或格式错误
  • 未在请求头中包含 Token

解决方案

  • 检查 Token 是否正确添加到请求头
  • 实现 Token 刷新机制
  • 确保 Token 格式正确(通常为 "Bearer your_token_here")

2. SSL 证书问题

原因

  • 自签名证书
  • 证书过期
  • 证书链不完整

解决方案: 对于开发环境,可以创建自定义 TrustManager:

代码语言:txt
复制
// 仅用于开发环境,生产环境应使用有效证书
OkHttpClient client = new OkHttpClient.Builder()
    .sslSocketFactory(getSSLSocketFactory(), getTrustManager())
    .hostnameVerifier((hostname, session) -> true)
    .build();

private static SSLSocketFactory getSSLSocketFactory() {
    try {
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, getTrustManager(), new SecureRandom());
        return sslContext.getSocketFactory();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private static TrustManager[] getTrustManager() {
    return new TrustManager[]{
        new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[]{};
            }
        }
    };
}

3. 网络连接问题

原因

  • 设备无网络连接
  • 服务器不可达
  • 防火墙阻止

解决方案

  • 检查网络连接状态
  • 添加超时设置
  • 实现重试机制
代码语言:txt
复制
OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .writeTimeout(15, TimeUnit.SECONDS)
    .retryOnConnectionFailure(true)
    .build();

最佳实践

  1. 使用 HTTPS:始终使用 HTTPS 传输敏感数据
  2. 短期 Token:使用短期有效的 Token 并实现刷新机制
  3. 安全存储:使用 Android 提供的安全存储机制
  4. 错误处理:妥善处理各种错误情况(网络错误、认证错误等)
  5. 日志记录:记录关键事件但不记录敏感信息
  6. Token 失效:实现 Token 失效检测和自动刷新

扩展应用

使用 Firebase Authentication

如果 API 支持 Firebase 认证:

代码语言:txt
复制
FirebaseAuth mAuth = FirebaseAuth.getInstance();

mAuth.signInWithEmailAndPassword(email, password)
    .addOnCompleteListener(task -> {
        if (task.isSuccessful()) {
            FirebaseUser user = mAuth.getCurrentUser();
            user.getIdToken(true)
                .addOnCompleteListener(tokenTask -> {
                    if (tokenTask.isSuccessful()) {
                        String token = tokenTask.getResult().getToken();
                        // 使用token访问API
                    }
                });
        }
    });

使用 OAuth2.0

对于 OAuth2.0 认证流程:

代码语言:txt
复制
// 使用AppAuth库实现OAuth2.0
AuthorizationService authService = new AuthorizationService(context);

AuthorizationRequest.Builder authRequestBuilder = new AuthorizationRequest.Builder(
    authConfig,
    clientId,
    ResponseTypeValues.CODE,
    Uri.parse("your://redirecturi")
);

authService.performAuthorizationRequest(
    authRequestBuilder.build(),
    PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0)
);

通过以上方法,您可以在 Java/Android 应用中安全地获取和使用 Web API 的 Token,并处理各种可能出现的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

没有搜到相关的合辑

领券