[Blocker] Redux 값 정리
로그인이 해제되어야 할 때(로그아웃)
로그인에 성공했을 때 받은 토큰을 redux store에 저장했다. 그런데 뒤로가기를 해서 로그인이 해제될 때를 어떻게 감지해서 토큰을 삭제해야 할지 고민이다. 새로운 로그인을 할 때 이전 로그인에서 받은 토큰이 있어도 덮어쓰기 때문에 상관은 없지만, 토큰이 남아있는 건 보안상 올바르지 않은 것 같다.
그래서 Login(시작화면)이나 PwVerify(비밀번호 입력) 화면에서는 항상 저장된 토큰이나 유저 정보 state가 있을 때 초기화하도록 코드를 썼다.
그랬더니 Login => PwVerify => Home => Bank 로 화면이 넘어가는데, Home에 온 다음 토큰이 삭제되어서 Bank로 넘어갈 때 로그인이 해제된다. 토큰을 삭제하는 코드에 문제가 생긴 것 같다.
그리고 Home으로 이동할 때나 Bank로 이동할 때도 이상하게 Login과 PwVerify에 찍어놓은 콘솔이 실행된다. 근데 이 문제는 해당 화면에서 토큰을 초기화한다고 redux state를 사용해서, 로그인에 성공해서 토큰에 값이 들어갈 때 코드가 실행되기 때문인 것 같다. 이게 전역 state를 이용할 때 주의할 점인가 싶다.
홈에서 뒤로가기 하면 앱 종료시키기
로그인해야 접속할 수 있는 Home으로 넘어간 다음 다시 로그인이나 비밀번호 입력 화면으로 돌아올 경우, 로그아웃시켜야 한다고 생각해서 토큰을 수동으로 삭제했는데 접근법이 잘못되었다. 토큰을 삭제할 필요 없이, 로그인하여 진행되는 화면을 벗어나면(홈에서 뒤로가기) 앱을 종료시키는 것이 적절하다.
[Blocker] 새로고침과 커스텀 훅
화면 새로고침
console.log로 확인해보면 새로고침 기능은 잘 작동하는 것 같다. 그런데 새로고침을 해도 point 잔액을 가져오는 API 호출 함수(useGetUser)가 다시 실행되지 않는다. 최초에 화면을 띄웠을 때는 당연히 실행되는데...
React Native에서 Android Native 연동
Native Module
//android.app.java.com.project_name.CalendarModule.java
package com.project_name;
//import static java.security.spec.MGF1ParameterSpec.SHA256;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
//import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.HashMap;
import android.util.Log;
public class CalendarModule extends ReactContextBaseJavaModule {
CalendarModule(ReactApplicationContext context) {
super(context);
}
@Override
public String getName() {
return "CalendarModule";
}
@ReactMethod
public void createCalendarEvent(final Promise promise, String name, String location) {
Log.d("CalendarModule", "Create event called with name: " + name
+ " and location: " + location);
//try{
// String encData = com.iaurora.util.SHA256.encrypt("test");
// promise.resolve(encData);
//}catch (Exception e){
//}
//promise.reject("dkdk","djdkdkdk");
}
}
모듈을 만든다. getName() 함수는 꼭 필요하다.
//android.app.java.com.project_name.MyAppPackage.java
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new CalendarModule(reactContext));
return modules;
}
MyAppPackage.java에 새로 만든 네이티브 모듈을 createNativeModules() 안에서 모듈화한다. modules.add(new CalendarModule(reactContext)); 이 부분을 추가하면 된다.
//android.app.java.com.project_name.MainApplication.java
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
// below MyAppPackage is added to the list of packages returned
packages.add(new MyAppPackage());
return packages;
}
MainApplication.java에 새로 만든 네이티브 모듈을 등록한다. 그래야 React Native에서 getPackages() 메서드를 이용해서 반환하게 된다.
import React from 'react';
import {NativeModules, Button} from 'react-native';
const Test = () => {
const {CalendarModule} = NativeModules;
const onPress = () => {
CalendarModule.createCalendarEvent('테스트이름', '테스트위치');
};
return (
<Button
title="Click to invoke your native module!"
color="#841584"
onPress={onPress}
/>
);
};
export default Test;
작업하던 리액트 네이티브 쪽에서 새로운 화면을 하나 만들어서 CalendarModule을 통해 콘솔에 임의의 문자열을 찍어보았다. 처음에 LogCat에 로그들이 무시무시하게 많이 올라와서 멈추지를 않았는데 어플을 종료했다가 다시 켜고 이리저리 했더니 멈췄다. 그리고 화면에 만들어둔 버튼을 클릭하면 콘솔이 찍혔다. 이외에 별다른 기능은 없어서 공식문서에서 만든 CalendarModule의 의미는 정확히 모르겠지만 안드로이드 네이티브로 모듈을 만들고, 리액트 네이티브에서 가져다 썼다는 것은 알겠다.
- 참고한 공식문서 : https://reactnative.dev/docs/native-modules-android
- React Native - 브릿지(Bridge)를 이용해 Android에서 Native Module 이용하기 : https://leonkong.cc/posts/react-native-android-bridge.html
- https://sonny777.tistory.com/37
- https://sansanji.tistory.com/entry/React-Native-%EA%B0%9C%EB%B0%9C%EC%8B%9C-Native-%EA%B8%B0%EB%8A%A5-%EA%B0%9C%EB%B0%9C%ED%9B%84-%EC%97%B0%EA%B2%B0-%EB%B0%A9%EB%B2%95-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C
- https://www.devh.kr/2020/Creating-a-Native-Module-in-React-Native/
Android Native에서 SHA256 코드
//android.app.java.com.project_name.util.SHA256.java
package com.project_name.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHA256 {
public static String encrypt(String text) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(text.getBytes());
return bytesToHex(md.digest());
}
private static String bytesToHex(byte[] bytes) {
StringBuilder builder = new StringBuilder();
for (byte b : bytes) {
builder.append(String.format("%02x", b));
}
return builder.toString();
}
}
인터넷에서 찾은 SHA256 암호화 코드를 util 폴더 안에 붙여넣는다.
//android.app.java.com.project_name.CalendarModule.java
...
try{
String encData = com.iaurora.util.SHA256.encrypt("test");
promise.resolve(encData);
}catch (Exception e){
}
...
이전에는 로그만 찍히는 코드였는데 이제 SHA256으로 문자열을 암호화한다. 이상하게도 이 코드가 지금은 작동되지 않기는 하다.
- 참고한 코드 : https://bamdule.tistory.com/233
- [Android] 문자열을 SHA-256로 암호화하기 (AndroidKeyStore 이용) : https://striban.tistory.com/67
공부할 것
- Promise
'TIL' 카테고리의 다른 글
[TIL-169] React Native (0) | 2022.04.19 |
---|---|
[TIL-168] React Native : 안드로이드 BackHandler 앱 종료, Promise로 fetch 동기 처리, 세션 (0) | 2022.04.18 |
[TIL-166] React Native (0) | 2022.04.14 |
[TIL-165] React Native (0) | 2022.04.13 |
[TIL-164] React Native (0) | 2022.04.12 |