데이터를 저장할때 데이터의 양이 많으면 서버 DB에 저장하면 된다.
하지만 간단한 데이터를 저장하기 위해 DB를 사용하는 것은 시간과 공간 낭비이다.
그래서 간단한 데이터를 저장하고 관리하기 위해 SharedPreferences를 사용한다.
1. 저장하기
put을 사용해서 값을 저장한다.
put뒤에 오는 건 저장할 데이터의 타입.
val pref = getSharedPreferences("test",MODE_PRIVATE)//'test'라는 이름 사용해서 저장
val editor = pref.edit()
editor.putString("test1", "테스트 1 입니다.") // String값 저장(test1이라는 이름으로 저장)
editor.putString("test2",true) // Boolean값 저장
editor.putInt("test3",3333) // Tnt값 저장
editor.apply() // 데이터 저장
2.읽어오기
get을 사용해서 값을 읽어온다.
val pref = getSharedPreferences("test",MODE_PRIVATE)
val value1 = pref.getString("test1","디폴트 값 입니다.")//test1로 저장된 곳에서 값을 가져온다.
val value2 = pref.getBoolean("test2",true)
val value3 = pref.getInt("test3",1)
지금까지 SharedPreferences의 간단한 사용법에 대해 알아보았다.
이제 sharedPreferences를 사용해서 토큰을 저장하는 법에 대해 알아보고자 한다.
먼저 JWT란 JSON객체를 사용해서 토큰 자체에 정보를 저장하는 Web Token이다.
Header, Payload, Signature 3개의 부분으로 구성되어 있으며 쿠키나 세션을 이용한 인증보다 안전하고 효율적이다.
public class Utils {
private static final String PREFS = "prefs";
private static final String Access_Token = "Access_Token";
private static final String Refresh_Token = "Refresh_Token";
private Context mContext;
private static SharedPreferences prefs;
private static SharedPreferences.Editor prefsEditor;
private static Utils instance;
public static synchronized Utils init(Context context) {
if(instance == null)
instance = new Utils(context);
return instance;
}
private Utils(Context context) {
mContext = context;
prefs = mContext.getSharedPreferences(PREFS,Context.MODE_PRIVATE);
prefsEditor = prefs.edit();
}
public static void setAccessToken(String value) {
prefsEditor.putString(Access_Token, value).commit();
}
public static String getAccessToken(String defValue) {
return prefs.getString(Access_Token,defValue);
}
public static void setRefreshToken(String value) {
prefsEditor.putString(Refresh_Token, value).commit();
}
public static String getRefreshToken(String defValue) {
return prefs.getString(Refresh_Token,defValue);
}
public static void clearToken() {
prefsEditor.clear().apply();
}
}
서버에 로그인 관련 정보를 post요청 하면 서버는 회원가입한 데이터를 기반으로 확인하고 토큰을 생성해서 응답으로 보내준다.
이부분은 로그인 하는 이메일과 비밀번호를 DTO로 보내면 응답값으로 토큰을 받는 인터페이스이다.
public interface SignIn {
@POST("/auth/login")
Call<TokenDto> getSignIn(@Body AccountLoginDto accountLoginDto);
}
이렇게 Utils클래스를 이용해서 SharedPreferences를 활용했다.
로그인 시 토큰을 발급받으면 access token과 refresh token을 받는데 이 토큰을 기반으로 서버에 api요청을 하거나 응답을 받는다.
그러므로 해당 토큰값을 안드로이드에 저장을 해서 필요할 때 사용을 해야한다.
앱 구조상 많은 데이터를 저장하는 것이 아니고, SharedPreferences에 key-value형태로 간단하게 저장을 하면 통신을 용이하게 할 수 있다.
이제 실제 로그인 시에 SharedPreferences로 저장한 토큰을 불러올것이다.
먼저 Retrofit 인스턴스를 만든 후에 로그인에 해당하는 인터페이스를 구현한다.
SignIn signIn = RetrofitBuilder.getRetrofit().create(SignIn.class);
public interface SignIn {
@POST("/auth/login")
Call<TokenDto> getSignIn(@Body AccountLoginDto accountLoginDto);
}
이 부분은 로그인하는 이메일과 비밀번호를 DTO로 보내면 응답값으로 토큰을 받는 부분이다.
이제 받은 Access Token과 RefreshToken을 앞서 만든 Utils클래스를 이용해서 SharedPreferences에 저장한다.
binding.btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
email = binding.etEmail.getText().toString();
password = binding.etPassword.getText().toString();
AccountLoginDto account = new AccountLoginDto(email, password);
Call<TokenDto> call = signIn.getSignIn(account);
call.enqueue(new Callback<TokenDto>() {
@Override
public void onResponse(Call<TokenDto> call, Response<TokenDto> response) {
if (!response.isSuccessful()) {
Log.e("연결이 비정상적 : ", "error code : " + response.code());
} else {
Utils.setAccessToken(response.body().getAccessToken());
Utils.setRefreshToken(response.body().getRefreshToken());
Log.e("Login", "at : " + Utils.getAccessToken("nein"));
Log.e("Login", "rt : " + Utils.getRefreshToken("none"));
}
}
@Override
public void onFailure(Call<TokenDto> call, Throwable t) {
}
});
Intent intentHome = new Intent(getApplicationContext(), HomeActivity.class);
startActivity(intentHome);
finish();
}
});