package ru.simplex2.vkid_spring_security.vk;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
/**
* Значения полей clientId и redirectUri этого класса нужно задать самостоятельно.
*/
public class VkSettings {
private static final String PKCE_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
private static final SecureRandom RANDOM = new SecureRandom();
/**
* ID Вашего приложения в VK ID.
* Узнать ID можно здесь:
* https://id.vk.com/about/business/go/
*/
private String clientId;
/**
* Uri адрес, по которому VK будет перенаправлять пользователя.
* Указывается там же, где указан Ваш clientId:
* https://id.vk.com/about/business/go/
*/
private String redirectUri;
private String codeVerifier;
public VkSettings(String redirectUri, String clientId) {
this.redirectUri = redirectUri;
this.clientId = clientId;
}
public String generateCodeVerifier() {
return generateCodeVerifier(64);
}
public String generateCodeVerifier(int length) {
if (length < 43 || length > 128) {
throw new IllegalArgumentException("code_verifier length must be between 43 and 128");
}
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
int idx = RANDOM.nextInt(PKCE_CHARSET.length());
sb.append(PKCE_CHARSET.charAt(idx));
}
return codeVerifier = sb.toString();
}
public String generateCodeChallenge(String codeVerifier) {
if (codeVerifier == null || codeVerifier.isEmpty()) {
throw new IllegalArgumentException("code_verifier must not be null or empty");
}
byte[] bytes = codeVerifier.getBytes(StandardCharsets.US_ASCII);
byte[] digest = sha256(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(digest);
}
private byte[] sha256(byte[] input) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
return md.digest(input);
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("SHA-256 not available", e);
}
}
public String getCodeVerifier() {
return codeVerifier;
}
public void setCodeVerifier(String codeVerifier) {
this.codeVerifier = codeVerifier;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getRedirectUri() {
return redirectUri;
}
public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
}