diff --git a/internal/api/provider/kakao.go b/internal/api/provider/kakao.go index 0963a918c5..2482b97a87 100644 --- a/internal/api/provider/kakao.go +++ b/internal/api/provider/kakao.go @@ -12,6 +12,7 @@ import ( const ( defaultKakaoAuthBase = "kauth.kakao.com" defaultKakaoAPIBase = "kapi.kakao.com" + IssuerKakao = "https://kauth.kakao.com" ) type kakaoProvider struct { diff --git a/internal/api/provider/oidc.go b/internal/api/provider/oidc.go index 56949dc3fb..01f7ab7e64 100644 --- a/internal/api/provider/oidc.go +++ b/internal/api/provider/oidc.go @@ -59,6 +59,8 @@ func ParseIDToken(ctx context.Context, provider *oidc.Provider, config *oidc.Con token, data, err = parseAppleIDToken(token) case IssuerLinkedin: token, data, err = parseLinkedinIDToken(token) + case IssuerKakao: + token, data, err = parseKakaoIDToken(token) default: if IsAzureIssuer(token.Issuer) { token, data, err = parseAzureIDToken(token) @@ -312,6 +314,43 @@ func parseAzureIDToken(token *oidc.IDToken) (*oidc.IDToken, *UserProvidedData, e return token, &data, nil } +type KakaoIDTokenClaims struct { + jwt.StandardClaims + + Email string `json:"email"` + Nickname string `json:"nickname"` + Picture string `json:"picture"` +} + +func parseKakaoIDToken(token *oidc.IDToken) (*oidc.IDToken, *UserProvidedData, error) { + var claims KakaoIDTokenClaims + + if err := token.Claims(&claims); err != nil { + return nil, nil, err + } + + var data UserProvidedData + + if claims.Email != "" { + data.Emails = append(data.Emails, Email{ + Email: claims.Email, + Verified: true, + Primary: true, + }) + } + + data.Metadata = &Claims{ + Issuer: token.Issuer, + Subject: token.Subject, + Name: claims.Nickname, + PreferredUsername: claims.Nickname, + ProviderId: token.Subject, + Picture: claims.Picture, + } + + return token, &data, nil +} + func parseGenericIDToken(token *oidc.IDToken) (*oidc.IDToken, *UserProvidedData, error) { var data UserProvidedData diff --git a/internal/api/token_oidc.go b/internal/api/token_oidc.go index 5695cb4894..58e022afdd 100644 --- a/internal/api/token_oidc.go +++ b/internal/api/token_oidc.go @@ -74,6 +74,12 @@ func (p *IdTokenGrantParams) getProvider(ctx context.Context, config *conf.Globa issuer = config.External.Keycloak.URL acceptableClientIDs = append(acceptableClientIDs, config.External.Keycloak.ClientID...) + case p.Provider == "kakao" || p.Issuer == provider.IssuerKakao: + cfg = &config.External.Kakao + providerType = "kakao" + issuer = provider.IssuerKakao + acceptableClientIDs = append(acceptableClientIDs, config.External.Kakao.ClientID...) + default: log.WithField("issuer", p.Issuer).WithField("client_id", p.ClientID).Warn("Use of POST /token with arbitrary issuer and client_id is deprecated for security reasons. Please switch to using the API with provider only!")