Sie können ein ID-Token (JWT) erhalten, wenn Sie sich mit der Firebase-Authentifizierung anmelden. Wenn Sie beispielsweise eine Anmeldeauthentifizierung mit SPA durchführen, möchten Sie sich möglicherweise mit Firebase mit einem Client (JavaScript) anmelden, das erworbene Token an den Server senden und die UID in JWT dem von der Anwendung verwalteten Benutzer zuordnen. Ich denke, dort ist.
Dieses Mal werde ich hauptsächlich die Überprüfungsmethode von JWT auf der Serverseite schreiben (Java + SpringBoot).
Dieses Mal werde ich Nuxt verwenden. So erhalten und senden Sie Token.
Authentifizierungsprozess (Auszug)
async signin() {
try {
//Authentifizieren Sie sich mit E-Mail-Adresse und Passwort
await firebase.auth().signInWithEmailAndPassword(this.email, this.password)
//ID-Token abrufen (JWT)
const token = await firebase.auth().currentUser.getIdToken(true)
//Im lokalen Speicher speichern
localStorage.setItem('token', token)
//Übergang zur Seite nach der Authentifizierung
this.$router.push('/')
} catch (e) {
//Zum Zeitpunkt des Authentifizierungsfehlers oder Token-Erfassungsfehlers
console.log(e)
}
}
~/plugins/axios.js
export default function ({ $axios }) {
$axios.onRequest(config => {
const token = localStorage.getItem('token');
if (token) {
//Wenn sich im lokalen Speicher ein Token befindet, geben Sie es an den Anforderungsheader weiter (Autorisierung).
config.headers.common['Authorization'] = "Bearer " + token;
}
})
}
Verwenden Sie den OnecePerRequestFilter von Spring Security.
Darüber hinaus werden die folgenden Bibliotheken verwendet.
Bibliotheksname | Verwenden |
---|---|
OkHttp | HTTP-Client |
jjwt | JWT-Überprüfung |
LoginFilter.java
@Component
public class LoginFilter extends OncePerRequestFilter {
//Registrieren Sie ObjectMapper im Voraus als Bean.
@Autowired
ObjectMapper objectMapper;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
//Legen Sie die Anmeldebenutzerinformationen im Kontext fest
SecurityContextHolder.getContext().setAuthentication(new PreAuthenticatedAuthenticationToken(
auth(request), null));
filterChain.doFilter(request, response);
}
//Holen Sie sich Login-Benutzerinformationen
private LoginUser auth(HttpServletRequest request) {
//JWT aus dem Anforderungsheader extrahieren
String token = getToken(request);
try {
//Überprüfen Sie JWT, erhalten Sie Ansprüche
//Wenn die Validierung fehlschlägt, wird eine Ausnahme ausgelöst.
Jws<Claims> claim = Jwts.parser()
.setSigningKeyResolver(new GoogleSigningKeyResolver()) //Benötigen Sie Ihren eigenen Resolver
.parseClaimsJws(token);
//Holen Sie sich Uid aus dem Körperteil des Anspruchs
String uid = (String)claim.getBody().get("user_id");
//Holen Sie sich UID und suchen Sie nach Benutzerinformationen
User user = userService.findByUid(uid);
if(user == null){
throw new BadCredentialsException("Benutzer existiert nicht");
}
return new LoginUser(user);
} catch (Exception e) {
throw new BadCredentialsException("Ungültiger Token");
}
}
//Holen Sie sich das Token aus dem Anforderungsheader.
private String getToken(HttpServletRequest request) {
String token = request.getHeader("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
return null;
}
return token.substring("Bearer ".length());
}
/**
*Wir geben den öffentlichen Schlüssel zurück, der zum Signieren verwendet wurde.
*
* @author h.ono
*
*/
public class GoogleSigningKeyResolver extends SigningKeyResolverAdapter {
@Override
public Key resolveSigningKey(JwsHeader jwsHeader, Claims claims) {
try {
Map<String, Object> map = getJwks();
if (map.isEmpty()) {
return null;
}
String keyValue = (String) map.get(jwsHeader.getKeyId());
if (keyValue == null) {
return null;
}
//Wichtiger Punkt
//Entfernen Sie die Start- (BEGIN) und Endetiketten (END).
keyValue = keyValue
.replaceAll("-----BEGIN CERTIFICATE-----\n", "")
.replaceAll("-----END CERTIFICATE-----\n", "");
InputStream in = new ByteArrayInputStream(Base64.decodeBase64(keyValue.getBytes("UTF-8")));
X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(in);
return certificate.getPublicKey();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
*Holen Sie sich JWKS von Google.
*
* @return JWKS
*/
private Map<String, Object> getJwks() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.googleapis.com/robot/v1/metadata/x509/[email protected]")
.build();
try (Response response = client.newCall(request).execute()) {
return objectMapper.readValue(response.body().string(), new TypeReference<Map<String, Object>>() {
});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
Ich konnte die von Firebase erhaltene UID dem Benutzer zuordnen, der die App hat. Ich habe viel recherchiert, aber der größte Teil der Authentifizierung wurde auf der Clientseite abgeschlossen, sodass ich Schwierigkeiten hatte, zu einer Methode wie dieser zu gelangen. .. ..
Bei der Überprüfung von JWT habe ich auch versucht, java-jwt von auth0 bereitzustellen, aber beim Abrufen des öffentlichen Schlüssels Ich konnte es wahrscheinlich nicht bekommen, weil es das X.509-Format nicht unterstützt.
Recommended Posts