From dcf16b5baeae8aff129b32937e973a66a65d0408 Mon Sep 17 00:00:00 2001 From: MiryangJung Date: Fri, 19 Jan 2024 09:28:05 +0900 Subject: [PATCH 1/2] feat: add kakao OIDC --- internal/api/provider/kakao.go | 1 + internal/api/provider/oidc.go | 40 ++++++++++++++++++++++++++++++++++ internal/api/token_oidc.go | 6 +++++ 3 files changed, 47 insertions(+) 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 be487dfc50..501ab753ec 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,44 @@ func parseAzureIDToken(token *oidc.IDToken) (*oidc.IDToken, *UserProvidedData, e return token, &data, nil } +type KakaoIDTokenClaims struct { + jwt.StandardClaims + + Email string `json:"email"` + EmailVerified bool `json:"email_verified"` + Name string `json:"name"` + 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: claims.EmailVerified, + Primary: true, + }) + } + + data.Metadata = &Claims{ + Issuer: token.Issuer, + Subject: token.Subject, + Name: claims.Name, + PreferredUsername: claims.Name, + 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 a5722f3676..a3e3fb5b32 100644 --- a/internal/api/token_oidc.go +++ b/internal/api/token_oidc.go @@ -75,6 +75,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!") From 57f67039f663436604930095847fb6bf9c79e5e2 Mon Sep 17 00:00:00 2001 From: MiryangJung Date: Mon, 22 Jan 2024 17:18:22 +0900 Subject: [PATCH 2/2] fix: Use the correct data key --- internal/api/provider/oidc.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/internal/api/provider/oidc.go b/internal/api/provider/oidc.go index 501ab753ec..a0ab76ceb2 100644 --- a/internal/api/provider/oidc.go +++ b/internal/api/provider/oidc.go @@ -317,10 +317,9 @@ func parseAzureIDToken(token *oidc.IDToken) (*oidc.IDToken, *UserProvidedData, e type KakaoIDTokenClaims struct { jwt.StandardClaims - Email string `json:"email"` - EmailVerified bool `json:"email_verified"` - Name string `json:"name"` - Picture string `json:"picture"` + Email string `json:"email"` + Nickname string `json:"nickname"` + Picture string `json:"picture"` } func parseKakaoIDToken(token *oidc.IDToken) (*oidc.IDToken, *UserProvidedData, error) { @@ -335,7 +334,7 @@ func parseKakaoIDToken(token *oidc.IDToken) (*oidc.IDToken, *UserProvidedData, e if claims.Email != "" { data.Emails = append(data.Emails, Email{ Email: claims.Email, - Verified: claims.EmailVerified, + Verified: true, Primary: true, }) } @@ -343,8 +342,8 @@ func parseKakaoIDToken(token *oidc.IDToken) (*oidc.IDToken, *UserProvidedData, e data.Metadata = &Claims{ Issuer: token.Issuer, Subject: token.Subject, - Name: claims.Name, - PreferredUsername: claims.Name, + Name: claims.Nickname, + PreferredUsername: claims.Nickname, ProviderId: token.Subject, Picture: claims.Picture, }