ฉันพบปัญหาเดียวกันขณะพัฒนาแบ็กเอนด์ด้วย Spring Boot และ OAuth2 ปัญหาที่ฉันพบคือถ้าอุปกรณ์หลายเครื่องใช้โทเค็นเดียวกันร่วมกันเมื่ออุปกรณ์หนึ่งรีเฟรชโทเค็นอุปกรณ์อื่นจะไร้เดียงสาและสั้นเรื่องยาวอุปกรณ์ทั้งสองป้อนในการรีเฟรชโทเค็น โซลูชันของฉันคือการแทนที่ค่าเริ่มต้นAuthenticationKeyGenerator
ด้วยการใช้งานแบบกำหนดเองซึ่งแทนที่DefaultAuthenticationKeyGenerator
และเพิ่มพารามิเตอร์ใหม่client_instance_id
ในส่วนผสมของตัวสร้างคีย์ ลูกค้ามือถือของฉันจะส่งพารามิเตอร์นี้ซึ่งจะต้องไม่ซ้ำกันในการติดตั้งแอพ (iOS หรือ Android) นี่ไม่ใช่ข้อกำหนดพิเศษเนื่องจากแอพมือถือส่วนใหญ่ติดตามอินสแตนซ์ของแอปพลิเคชันในบางรูปแบบอยู่แล้ว
public class EnhancedAuthenticationKeyGenerator extends DefaultAuthenticationKeyGenerator {
public static final String PARAM_CLIENT_INSTANCE_ID = "client_instance_id";
private static final String KEY_SUPER_KEY = "super_key";
private static final String KEY_CLIENT_INSTANCE_ID = PARAM_CLIENT_INSTANCE_ID;
@Override
public String extractKey(final OAuth2Authentication authentication) {
final String superKey = super.extractKey(authentication);
final OAuth2Request authorizationRequest = authentication.getOAuth2Request();
final Map<String, String> requestParameters = authorizationRequest.getRequestParameters();
final String clientInstanceId = requestParameters != null ? requestParameters.get(PARAM_CLIENT_INSTANCE_ID) : null;
if (clientInstanceId == null || clientInstanceId.length() == 0) {
return superKey;
}
final Map<String, String> values = new LinkedHashMap<>(2);
values.put(KEY_SUPER_KEY, superKey);
values.put(KEY_CLIENT_INSTANCE_ID, clientInstanceId);
return generateKey(values);
}
}
ซึ่งคุณจะฉีดในลักษณะที่คล้ายกัน:
final JdbcTokenStore tokenStore = new JdbcTokenStore(mDataSource);
tokenStore.setAuthenticationKeyGenerator(new EnhancedAuthenticationKeyGenerator());
คำขอ HTTP จะมีลักษณะเช่นนี้
POST /oauth/token HTTP/1.1
Host: {{host}}
Authorization: Basic {{auth_client_basic}}
Content-Type: application/x-www-form-urlencoded
grant_type=password&username={{username}}&password={{password}}&client_instance_id={{instance_id}}
ประโยชน์ของการใช้วิธีนี้คือถ้าลูกค้าไม่ส่งclient_instance_id
คีย์เริ่มต้นจะถูกสร้างขึ้นและหากมีการให้อินสแตนซ์คีย์เดียวกันจะถูกส่งกลับทุกครั้งสำหรับอินสแตนซ์เดียวกัน นอกจากนี้ที่สำคัญคือแพลตฟอร์มอิสระ ข้อเสียก็คือการแยกย่อย MD5 (ใช้ภายใน) เรียกว่าสองครั้ง