Also available in English at Medium.com.
In diesem Blog-Post stellen wir die Client-Generierung von Swagger vor, zeigen, wie man die generierte API in React-Anwendungen verwendet und wie man das Authentifizierungs-Token von Auth0 integriert.
Der Einfachheit halber wird dieses Thema in eine dreiteilige Serie aufgeteilt:
Im zweiten Teil unserer Blogpost-Serie sichern wir unsere Web-Anwendung mit OAuth2 unter Verwendung von Auth0. Auth0 nennt sich selbst “eine einfach zu implementierende, anpassungsfähige Authentifizierungs- und Autorisierungsplattform” und bietet einen kostenlosen Tarif für bis zu 7000 Benutzer an. In diesem Beitrag wird die Integration von Auth0 in das Spring Boot Backend und die React-Webanwendung behandelt.
TL;DR
src/main/resources/application.properties
den Wert spring.security.oauth2.resourceserver.jwt.issuer-uri=https://<tenant>.eu.auth0.com
, um den neuen Tenant zu nutzen.no-security
-Profil.yarn install
.REACT_APP_DOMAIN=<IHRE_DOMAIN> (z.B.: https://miragon-example-tenant.eu.auth0.com); REACT_APP_CLIENT_ID=<IHRE_CLIENT_ID> (z.B.: yXu7adklfU729Hgsdg93p0gag9dC);
yarn start
.Setzen Sie in der src/main/resources/application.properties
den Wert spring.security.oauth2.resourceserver.jwt.issuer-uri=<AUTH0_TENANT_DOMAIN>
, um Ihren Auth0-Tenant zu verwenden. Die Domain kann auf der Anwendungsseite in Auth0 gefunden werden.
Sie können Ihr Backend mit der folgenden Security-Konfiguration schützen (Sie finden diese Klasse im Beispiel-Backend im Ordner shared/security):
@Profile("!no-security") @EnableWebSecurity @RequiredArgsConstructor public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(final HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/actuator/health").permitAll() .antMatchers("/v3/api-docs/**", "/swagger-resources", "/swagger-resources/**", "/configuration/ui", "/configuration/security", "/swagger-ui.html", "/swagger-ui/**", "/webjars/**").permitAll() .anyRequest() .authenticated() .and() .oauth2ResourceServer( OAuth2ResourceServerConfigurer::jwt ); http.headers().frameOptions().sameOrigin(); http.csrf().disable(); http.sessionManagement() .sessionCreationPolicy( SessionCreationPolicy.STATELESS ); } @Bean public JwtDecoder jwtDecoderByIssuerUri( final OAuth2ResourceServerProperties properties ) { final String issuerUri = properties.getJwt().getIssuerUri(); return JwtDecoders.fromIssuerLocation(issuerUri); } }
Wir werden Auth0s Benutzername & Passwort-Authentifizierung verwenden, die erscheinen sollte, wenn der Benutzer nicht angemeldet ist.
Der Login-Screen von Auth0:
Installieren Sie die erforderliche Abhängigkeit über yarn add @auth0/auth0-react
und fügen Sie den Provider in Ihre Anwendung ein (index.tsx):
<Auth0Provider domain={process.env.REACT_APP_DOMAIN ?? ""} clientId={process.env.REACT_APP_CLIENT_ID ?? ""} authorizeTimeoutSeconds={5} useRefreshTokensIn redirectUri={window.location.origin}> <HashRouter> <App/> </HashRouter> </Auth0Provider>
Die Domain und die Client-ID finden Sie in der Auth0-Anwendung, die Sie oben erstellt haben.
Wenn sich der Benutzer erfolgreich angemeldet hat, können wir nun das JWT-Token im lokalen Browser-Speicher ablegen, um von jeder Seite aus darauf zuzugreifen (src/components/Layout/Layout.tsx):
(async () => { const token = await getIdTokenClaims(); localStorage.setItem("token", token.__raw) })();
Der Token im lokalen Browser-Speicher:
Verwenden Sie die Configuration-Klasse, um den Authentifizierungsheader zu setzen (src/constants/Functions.tsx):
getClientConfig: function (): Configuration { return new Configuration({ baseOptions: { "headers": { 'Authorization': `Bearer ${this.getBearerToken()}`, } } }) }, getBearerToken: function (): string | null { return localStorage.getItem("token"); }
Mit dieser Konfiguration können Sie jetzt authentifizierte Anfragen an die gesicherten Endpoints Ihres Backends senden:
const config = getClientConfig(); const projectController = new ProjectControllerApi(config) const response = await projectController.getAllProject() const data = response.data
Im dritten - und letzten - Teil dieser Serie werden wir einen genaueren Blick darauf werfen, wie man den generierten API-Client als Teil einer React Native App verwendet. Bis zum nächsten Mal!
Rechtliches