이 글에서는 주로 마이크로서비스에서의 인증 구현 아이디어를 소개합니다. 이를 달성하기 위한 좋은 해결책이 있습니까? 함께 살펴보시고, 모두에게 도움이 되었으면 좋겠습니다.
최근 위챗에서 몇몇 친구들이 우연히 이런 질문을 해서 여러분과 이야기를 나누게 되었습니다. 이 글은 주로 코드를 작성하지 않고도 친구들과 아이디어에 대해 이야기하는 것입니다. 이 글의 코드를 직접 작성해보세요. 물론, 이 아이디어는 단지 저의 실제 경험일 뿐이며 가장 완벽한 해결책이 아닐 수도 있습니다. 친구들이 댓글을 통해 이에 대해 토론하는 것을 환영합니다.
먼저 친구들은 Shiro를 공부하든 Spring Security를 공부하든, 어떤 기능이 있든 핵심은 두 가지라는 것을 알고 있습니다:
인증
인증
따라서 마이크로서비스에서 인증 문제를 다룰 때 이 두 가지 측면도 고려할 수 있습니다.
인증이란 직설적으로 말하면 로그인을 의미합니다. 기존 웹 로그인은 서버의 로컬 메모리에 의존하는 쿠키+세션 솔루션입니다. 마이크로서비스에서는 서비스 수가 많기 때문에 이 솔루션은 더 이상 적합하지 않습니다.
어떤 친구들은 세션 공유를 위해 Redis+SpringSession을 사용하라고 말할 수도 있습니다. 이것은 방법이지만 이 솔루션의 성능과 확장성이 상대적으로 열악하기 때문에 최선의 솔루션은 아닙니다.
따라서 마이크로서비스에서는 인증을 위해 토큰을 사용하는 것이 좋습니다. 현재 일반적으로 사용되는 솔루션이기도 한 JWT 토큰을 선택할 수 있습니다. 그러나 JWT에 익숙한 친구들은 순수 상태 비저장 로그인이 로그아웃을 달성할 수 없다는 것을 알고 있으며 이는 매우 번거로운 일입니다. 따라서 실제 애플리케이션에서는 단순히 JWT를 사용하는 것만으로는 충분하지 않습니다. 일반적으로 생성된 JWT를 변환하려면 Redis와 결합해야 합니다. 문자열은 Redis에도 저장되며 만료 시간이 설정됩니다. 사용자가 로그인했는지 확인할 때 먼저 Redis에 JWT 문자열이 있는지 확인한 다음 JWT 문자열을 구문 분석해야 합니다. 성공적으로 구문 분석할 수 있으면 문제가 없습니다. 성공적으로 구문 분석할 수 없으면 토큰이 불법이라는 의미입니다.
상태 저장 로그인과 상태 비저장 로그인을 혼합하는 이러한 방식은 다소 설명이 없어 보일 수 있지만 현재로서는 이 타협 방법이 실행 가능한 솔루션으로 간주됩니다.
사실 위의 솔루션은 솔직하게 말하면 전통적인 Cookie+Session과 다르지 않습니다. 아이디어는 거의 완전히 복사되었습니다. 전통적인 Session은 서버와 서버 사이를 왕복하는 전통적인 jsessionId로 대체됩니다. 대신 브라우저는 JWT 문자열입니다. 기존 jsessionId는 쿠키를 통해 전송되며 현재 JWT는 개발자가 수동으로 설정하고 요청 헤더를 통해 전송됩니다. 기존 세션은 자동으로 갱신될 수 있지만 이제 JWT는 수동으로 갱신되며 각 요청은 시간이 되면 Redis에서 토큰의 만료 시간을 확인하세요. 만료가 가까워지면 다른 모든 사항은 동일하게 설정됩니다.
이것은 귀하가 선택한 인증 제도입니다.
마이크로서비스의 권한 부여는 Shiro 또는 Spring Security 프레임워크를 사용하여 수행할 수도 있으므로 문제가 발생하지 않습니다. 마이크로서비스 기술 스택이 Spring 제품군의 제품이라는 점을 고려하면 먼저 권한 프레임워크 측면에서 Spring Security를 선택하는 것이 좋습니다(친구가 Spring Security에 익숙하지 않은 경우 WeChat 백그라운드에서 ss에 응답할 수 있음). 공식 계정에는 튜토리얼이 있습니다) .
물론, Spring Security가 더 복잡하다고 생각하고 직접 해보고 싶다면 그렇게 할 수 있습니다. 직접 수행한다면 Spring Security의 아이디어를 사용할 수도 있습니다. Song Ge의 최근 프로젝트 중 하나는 다음과 같습니다.
요청이 마이크로서비스에 도달한 후 먼저 다음을 포함하여 현재 사용자에 대한 다양한 정보를 찾습니다. 현재 사용자가 소유한 역할 및 권한 정보를 기다린 후 현재 스레드에 바인딩된 ThreadLocal 개체에 저장합니다. 반면에 권한 주석 및 역할 주석을 사용자 정의하고 이러한 주석을 측면에서 구문 분석하고 현재 사용자에게 필요한 역할/권한 등이 있는지 확인하십시오.
물론, Spring Security를 사용한다면 위와 같은 커스텀 어노테이션은 필요하지 않습니다. 그냥 Spring Security에서 제공되는 어노테이션을 사용하면 됩니다. 또한 Spring Security에서 더욱 풍부한 보안 기능을 경험할 수도 있습니다.
그럼 인증과 승인은 어디서 하나요?
먼저 인증에 대해 이야기해 보겠습니다. 인증은 간단히 두 단계로 나눌 수 있습니다.
Login
Verification
일반적으로 로그인을 위한 별도의 인증 서비스를 수행할 수 있습니다. 로그인 요청이 게이트웨이에 도달하면 이를 인증 서비스로 전달하여 인증 작업을 완료합니다.
인증 서비스에서는 사용자 이름/비밀번호가 괜찮은지, 사용자 상태가 괜찮은지 확인합니다. 문제가 없으면 JWT 문자열을 생성하고 데이터를 Redis에 저장한 후 JWT 문자열을 반환합니다.
시스템에 등록 기능이 있는 경우 이 마이크로서비스에서도 등록 기능이 완료됩니다.
확인이란 각 요청이 도착할 때 사용자가 로그인했는지 여부를 확인하는 것을 말합니다.
물론 2.1에서도 가능하지만 송형제는 권장하지 않습니다. 문제는 주문 생성 요청인 경우 이 요청이 원래 게이트웨이를 통해 주문 서비스로 전달된다는 점입니다. 그러나 이때 로그인 확인을 위해 2.1절의 서비스를 게이트웨이에서 호출해야 합니다. 문제 없습니다. 주문 서비스 측면에서 이는 분명히 시간이 많이 걸리고 불합리한 일입니다.
더 좋은 방법은 요청한 토큰이 게이트웨이에서 합법적인지 직접 확인하는 것입니다. 이 확인 자체는 토큰이 합법적인지 확인하려면 해당 토큰이 Redis에 존재하는지 확인하면 됩니다. JWT 토큰을 원활하게 구문 분석할 수 있으므로 이 작업은 게이트웨이에서 수행될 수 있습니다.
게이트웨이를 예로 들면, 글로벌 필터를 사용자 정의하고 글로벌 필터에서 각 요청의 토큰을 확인할 수 있습니다. 확인이 통과되면 요청이 전달되고, 그렇지 않으면 전달되지 않습니다.
검증을 통과한 후 특정 마이크로서비스로 전달한 후 구문 분석된 사용자 ID, 사용자 이름 및 기타 정보를 요청 헤더에 넣은 다음 이를 전달할 수 있습니다. 그러면 각 특정 마이크로서비스에 도달한 후 누가 보낸 것인지 알 수 있습니다. 이 요청은 어떤 역할/권한을 갖고 있습니까? 이렇게 하면 권한 확인의 다음 단계가 쉬워집니다.
Song Ge가 한 일은 공용 모듈을 정의한 것입니다. 모든 마이크로서비스는 이 공용 모듈에 정의되어 있으며, 모든 요청을 가로채고 요청 헤더에서 사용자 ID를 가져온 다음 가져옵니다. Redis에서 특정 사용자 정보를 가져와 ThreadLocal에 저장합니다. 후속 메서드 호출에서 사용자에게 특정 권한이 있는지 확인해야 하는 경우 ThreadLocal을 통해 해당 정보를 얻을 수 있습니다.
대략 이런 과정이에요.
게이트웨이에서는 인증을 수행할 수 없으며 각 마이크로서비스에서 인증을 수행해야 합니다.
마이크로서비스에 대한 인증은 대략 두 가지 범주로 나눌 수 있습니다.
프런트 엔드에서 보낸 요청(외부 요청).
다른 마이크로서비스에서 보낸 요청(내부 요청)
외부 요청의 경우 일반적인 권한 확인에 따라 처리하거나 Spring Security와 같은 프레임워크를 사용하는 것이 허용됩니다. 사용자 정의 주석인 경우 AOP와 함께 정의하면 됩니다. 물론 이러한 기능은 기본적으로 모든 마이크로서비스에 필요하므로 공용 모듈로 추출하여 다양한 마이크로서비스에 의존할 수 있습니다.
내부 요청의 경우 일반적으로 인증이 필요하지 않으며 내부 요청을 직접 처리할 수 있습니다. 문제는 OpenFeign을 사용하면 인터페이스를 통해 데이터가 노출된다는 점입니다. 이 인터페이스를 호출하는 외부 요청에 대해 걱정할 수도 있습니다. 이 문제를 위해 주석 + AOP를 사용자 정의한 다음 호출할 때, 이를 구별하기 위해 추가 헤더 필드를 추가하십시오.
물론, 내부 요청이 마이크로서비스에 도달할 때 요청이 게이트웨이에서 각 특정 마이크로서비스로 전달될 때와 마찬가지로 인증도 필요합니다. 그러나 분명히 OpenFeign을 사용하여 다른 서비스를 호출할 필요는 없습니다. feign.RequestInterceptor
인터페이스를 구현하여 OpenFeign 요청 인터셉터를 정의할 수 있으며, 요청 헤더 정보는 OpenFeign 요청에 대해 균일하게 설정됩니다.
그렇습니다. 마이크로서비스 인증에 관해서는 현재 이렇게 하고 있습니다. 친구들이 메시지를 남기고 함께 토론하는 것을 환영합니다.
추천 학습: "Mini 프로그램 비디오 튜토리얼" "Java 비디오 튜토리얼"
위 내용은 마이크로서비스 인증 구현 방법을 자세히 설명하는 기사의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!