在Android App中使用JWT来进行API会话管理的良好实践,可以按照以下步骤进行:
implementation 'com.auth0.android:jwtdecode:2.1.0'
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.0'
SessionManager
类来管理JWT会话,该类负责生成、保存和验证JWT。import com.auth0.android.jwt.JWT;
public class SessionManager {
private static final String KEY_TOKEN = "token";
private static final String KEY_EXPIRES_AT = "expires_at";
private SharedPreferences preferences;
public SessionManager(Context context) {
preferences = context.getSharedPreferences("session", Context.MODE_PRIVATE);
}
public void saveToken(String token) {
SharedPreferences.Editor editor = preferences.edit();
editor.putString(KEY_TOKEN, token);
editor.apply();
}
public String getToken() {
return preferences.getString(KEY_TOKEN, null);
}
public boolean isTokenValid() {
String token = getToken();
if (token != null) {
JWT jwt = new JWT(token);
return !jwt.isExpired(0); // 设置0表示当前时间
}
return false;
}
public void clearToken() {
SharedPreferences.Editor editor = preferences.edit();
editor.remove(KEY_TOKEN);
editor.remove(KEY_EXPIRES_AT);
editor.apply();
}
}
SessionManager
中。import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import java.io.IOException;
public class LoginActivity extends AppCompatActivity {
private SessionManager sessionManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
sessionManager = new SessionManager(this);
// 登录按钮点击事件
Button loginButton = findViewById(R.id.loginButton);
loginButton.setOnClickListener(v -> {
String username = ((EditText) findViewById(R.id.usernameEditText)).getText().toString();
String password = ((EditText) findViewById(R.id.passwordEditText)).getText().toString();
login(username, password);
});
}
private void login(String username, String password) {
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
RequestBody formBody = new FormBody.Builder()
.add("username", username)
.add("password", password)
.build();
Request request = new Request.Builder()
.url("https://example.com/api/login")
.post(formBody)
.build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
String token = response.body().string();
sessionManager.saveToken(token);
// 登录成功,跳转到主界面
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
// 登录失败,显示错误信息
String errorMessage = response.body().string();
Toast.makeText(this, errorMessage, Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class ApiClient {
private static final String BASE_URL = "https://example.com/api/";
public static OkHttpClient getClient(Context context) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.addInterceptor(chain -> {
SessionManager sessionManager = new SessionManager(context);
Request originalRequest = chain.request();
Request.Builder requestBuilder = originalRequest.newBuilder();
if (sessionManager.isTokenValid()) {
requestBuilder.header("Authorization", "Bearer " + sessionManager.getToken());
}
Request newRequest = requestBuilder.build();
return chain.proceed(newRequest);
});
return builder.build();
}
public static ApiService getApiService(Context context) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(getClient(context))
.addConverterFactory(GsonConverterFactory