Token 是一种用于身份验证和授权的凭证,通常由服务器颁发,客户端在后续请求中携带以证明身份。在 Web API 中常用的是 JWT (JSON Web Token)。
// 定义认证接口
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) {
// 处理错误
}
});
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");
}
}
}
EncryptedSharedPreferences
存储 TokenAndroidKeyStore
加密存储// 使用 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 刷新机制以处理过期问题:
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;
}
}
原因:
解决方案:
原因:
解决方案: 对于开发环境,可以创建自定义 TrustManager:
// 仅用于开发环境,生产环境应使用有效证书
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[]{};
}
}
};
}
原因:
解决方案:
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();
如果 API 支持 Firebase 认证:
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 认证流程:
// 使用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,并处理各种可能出现的问题。