retrofit+okhttp+coroutines Token 실효 차단 (4가지 토큰 실효 해결 방안)

2511 단어 안드로이드

배경


Token은 현재 클라이언트가 서버에 가서 인증을 하는 데 사용되는 비교적 흔히 볼 수 있는 메커니즘이다.클라이언트는 먼저 사용자 이름, 비밀번호를 통해 서버에 로그인하여 token을 가져오고 다음에 요청할 때마다 token을 가져옵니다.Token이 유효기간 내에 서버가 모두 검사를 통과하고 효력을 상실하면 감권이 실패하고 클라이언트가 다시 로그인하여 token을 받아야 합니다.만약 시간이 지나면 사용자가 한 번 로그인해야 한다면, 이것은 분명히 매우 우호적이지 않다.그럼 어떡하지?

솔루션

  • 방안 1. token 설정은 영원히 유효하다.이것은 분명히 다음 방법이다. 일단 토큰이 잡히면 놀아 죽는다
  • 방안 2. 앱이 시작되면 token이 효력을 잃는지 검사하고 만약에 그렇다면 자동으로 로그인하여 token을 새로 고칩니다. 앱이 실행 중일 때 token을 정기적으로 검사하고 새로 고칩니다
  • 방안 3. 매번 요청 전에 token이 효력을 잃을지 판단하고 만약에 그렇다면 자동으로 로그인하여 token을 갱신하고 원래의 요청을 보냅니다
  • 방안 4. Token 실효 차단.모든 요청(상륙 요청 제외)을 차단하고 토큰이 효력을 잃으면 자동으로 로그인하여 토큰을 갱신하고 원래 요청을 보냅니다.본고는 이 방안의 구체적인 실현 방식만 소개한다

  • Token 실효 차단 실현 방법

  • okhttp에 차단기를 설정합니다. 그 중에서 HttpHeaderInterceptor는 모든 요청에 token 필드를 추가하는 차단기입니다.Token Interceptor는 Token의 실효 여부를 검사하고 다시 로그인하는 차단기입니다.
  • OkHttpClient.Builder()
    .apply {
        addInterceptor(HttpHeaderInterceptor())
        addInterceptor(TokenInterceptor())
    }.build()
    
  • token 차단기에서 반환 정보에 대해 실효 여부를 판단해야 한다.효력을 잃으면 자동으로 로그인한 다음 원래 요청을 다시 실행합니다.주의: 자동 로그인 시, 더 이상 coroutines 비동기적으로 실행할 수 없습니다. 반드시 동기화 방식을 사용해야 로그인 후 원래 요청을 실행하고 실행 결과를 호출자에게 되돌려줄 수 있습니다
  • class TokenInterceptor : BaseInterceptor() {
        override fun interceptMe(chain: Interceptor.Chain): Response {
            val request = chain.request()
            var response = chain.proceed(request)
            if (isTokenExpired(response)) {
                response = loginAndReSendOriginalRequest(request, response, chain)
            }
    
            return response
        }
    
        /**
         *  , 
         */
        private fun loginAndReSendOriginalRequest(request: Request, originalResponse: Response,
                                                  chain: Interceptor.Chain): Response {
            var response = originalResponse
            LoginManager.login(
                    onSuccess = {
                        val newRequest = replaceTokenInHeader(request, it.token)
                        response?.close()
                        response = chain.proceed(newRequest)
                    }
            )
            return response
        }
    
        /**
         *  token 。
         * TODO:  isTokenExpired , true; 。
         */
        private fun isTokenExpired(response: Response) = true//(response.code() == TOKEN_EXPIRED)
    }```
    
    # Demo 
    https://gitee.com/cxyzy1/coroutineRetrofitDemo.git
    
    
    
    
    
    
     : https://blog.csdn.net/yinxing2008/article/details/84555061
    [ , ](https://blog.csdn.net/yinxing2008/column/info/34054)
     , :「 」
    

    좋은 웹페이지 즐겨찾기