Files
neo-blog/pkg/utils/oidc.go
Snowykami 9ca307f4d9 ️ feat: add main page layout with navigation and footer
feat: create random labels page

feat: implement login page with OpenID Connect support

feat: add Gravatar component for user avatars

feat: create Navbar component with navigation menu

chore: create Sidebar component placeholder

feat: implement login form with OIDC and email/password options

feat: add reusable button component

feat: create card component for structured content display

feat: implement input component for forms

feat: create label component for form labels

feat: add navigation menu component for site navigation

chore: add configuration file for site metadata

feat: implement device context for responsive design

feat: add utility functions for class name management

feat: define OIDC configuration model

feat: define base response model for API responses

feat: define user model for user data

feat: implement i18n for internationalization support

feat: add English and Chinese translations for login

chore: create index for locale resources

chore: add blog home view placeholder
2025-07-24 09:22:50 +08:00

72 lines
1.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package utils
import (
"fmt"
"resty.dev/v3"
)
type oidcUtils struct{}
var Oidc = oidcUtils{}
// RequestToken 请求访问令牌
func (u *oidcUtils) RequestToken(tokenEndpoint, clientID, clientSecret, code, redirectURI string) (*TokenResponse, error) {
client := resty.New()
tokenResp, err := client.R().
SetFormData(map[string]string{
"grant_type": "authorization_code",
"client_id": clientID,
"client_secret": clientSecret,
"code": code,
"redirect_uri": redirectURI,
}).
SetHeader("Accept", "application/json").
SetResult(&TokenResponse{}).
Post(tokenEndpoint)
if err != nil {
return nil, err
}
if tokenResp.StatusCode() != 200 {
return nil, fmt.Errorf("状态码: %d响应: %s", tokenResp.StatusCode(), tokenResp.String())
}
return tokenResp.Result().(*TokenResponse), nil
}
// RequestUserInfo 请求用户信息
func (u *oidcUtils) RequestUserInfo(userInfoEndpoint, accessToken string) (*UserInfo, error) {
client := resty.New()
userInfoResp, err := client.R().
SetHeader("Authorization", "Bearer "+accessToken).
SetHeader("Accept", "application/json").
SetResult(&UserInfo{}).
Get(userInfoEndpoint)
if err != nil {
return nil, err
}
if userInfoResp.StatusCode() != 200 {
return nil, fmt.Errorf("状态码: %d响应: %s", userInfoResp.StatusCode(), userInfoResp.String())
}
return userInfoResp.Result().(*UserInfo), nil
}
type TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
IDToken string `json:"id_token,omitempty"`
RefreshToken string `json:"refresh_token,omitempty"`
}
// UserInfo 定义用户信息结构
type UserInfo struct {
Sub string `json:"sub"`
Name string `json:"name"`
Email string `json:"email"`
Picture string `json:"picture,omitempty"`
Groups []string `json:"groups,omitempty"` // 可选字段OIDC提供的用户组信息
}