Documentation ¶
Overview ¶
Package gitkit provides convenient utilities for third party website to integrate Google Identity Toolkit.
See more at https://developers.google.com/identity-toolkit
To use Identity Toolkit Go client:
var client *gitkit.Client func handleSignIn(w http.ResponseWriter, r *http.Request) { // If there is no valid session, check identity tookit ID token. ts := client.TokenFromRequest(r) token, err := client.ValidateToken(context.Background(), ts, []string{clientID}) if err != nil { // Not a valid token. Handle error. } // Token is validate and it contains the user account information // including user ID, email address, etc. // Issue your own session cookie to finish the sign in. } func main() { // Provide configuration. gitkit.LoadConfig() can also be used to load // the configuration from a JSON file. config := &gitkit.Config{ ClientID: "123.apps.googleusercontent.com", WidgetURL: "http://localhost/gitkit", CookieName: "gtoken", } var err error client, err = gitkit.New(context.Background(), config) if err != nil { // Handle error. } // Provide HTTP handler. http.HandleFunc("/signIn", handleSignIn) // Start the server. log.Fatal(http.ListenAndServe(":8080", nil)) }
The integration with Google App Engine is similar except for the context variable should be created from the request, i.e., appengine.NewContext(r):
var client *gitkit.Client func handleSignIn(w http.ResponseWriter, r *http.Request) { // If there is no valid session, check identity tookit ID token. ts := client.TokenFromRequest(r) token, err := client.ValidateToken(appengine.NewContext(r), ts, []string{clientID}) if err != nil { // Not a valid token. Handle error. } // Token is validate and it contains the user account information // including user ID, email address, etc. // Issue your own session cookie to finish the sign in. } func init() { // Provide configuration. gitkit.LoadConfig() can also be used to load // the configuration from a JSON file. config := &gitkit.Config{ ClientID: "123.apps.googleusercontent.com", WidgetURL: "http://localhost/gitkit", CookieName: "gtoken", } // Set the JSON key file path if running dev server in local. if appengine.IsDevAppServer() { c.GoogleAppCredentialsPath = googleAppCredentialsPath } var err error client, err = gitkit.New(context.Background(), config) if err != nil { // Handle error. } // Provide HTTP handler. http.HandleFunc("/signIn", handleSignIn) // Start the server. log.Fatal(http.ListenAndServe(":8080", nil)) }
The Go client uses Google Application Default Credentials to access authentication required Identity Toolkit API. The credentials returned are determined by the environment the code is running in. Conditions are checked in the following order:
1. The environment variable GOOGLE_APPLICATION_CREDENTIALS is checked. If this variable is specified it should point to a file that defines the credentials. The simplest way to get a credential for this purpose is to create a service account using the Google Developers Console in the section APIs & Auth, in the sub-section Credentials. Create a service account or choose an existing one and select Generate new JSON key. Set the environment variable to the path of the JSON file downloaded.
2. If you have installed the Google Cloud SDK on your machine and have run the command gcloud auth login, your identity can be used as a proxy to test code calling APIs from that machine.
3. If you are running in Google App Engine production, the built-in service account associated with the application will be used.
4. If you are running in Google Compute Engine production, the built-in service account associated with the virtual machine instance will be used.
5. If none of these conditions is true, an error will occur.
See more about Google Application Default Credentials at https://developers.google.com/identity/protocols/application-default-credentials
If Application Default Credentials doesn't work for your use case, you can set GoogleAppCredentialsPath in the config to the JSON key file path.
Index ¶
- Constants
- Variables
- func ErrorResponse(err error) string
- func SuccessResponse() string
- type APIClient
- func (c *APIClient) DeleteAccount(req *DeleteAccountRequest) (*DeleteAccountResponse, error)
- func (c *APIClient) DownloadAccount(req *DownloadAccountRequest) (*DownloadAccountResponse, error)
- func (c *APIClient) GetAccountInfo(req *GetAccountInfoRequest) (*GetAccountInfoResponse, error)
- func (c *APIClient) GetOOBCode(req *GetOOBCodeRequest) (*GetOOBCodeResponse, error)
- func (c *APIClient) GetProjectConfig() (*GetProjectConfigResponse, error)
- func (c *APIClient) SetAccountInfo(req *SetAccountInfoRequest) (*SetAccountInfoResponse, error)
- func (c *APIClient) UploadAccount(req *UploadAccountRequest) (*UploadAccountResponse, error)
- type Bytes
- type Certificates
- type Client
- func (c *Client) DeleteUser(ctx context.Context, user *User) error
- func (c *Client) GenerateChangeEmailOOBCode(ctx context.Context, req *http.Request, email, newEmail, token string) (*OOBCodeResponse, error)
- func (c *Client) GenerateOOBCode(ctx context.Context, req *http.Request) (*OOBCodeResponse, error)
- func (c *Client) GenerateResetPasswordOOBCode(ctx context.Context, req *http.Request, ...) (*OOBCodeResponse, error)
- func (c *Client) GenerateVerifyEmailOOBCode(ctx context.Context, req *http.Request, email string) (*OOBCodeResponse, error)
- func (c *Client) GetProjectConfig(ctx context.Context) (*ProjectConfig, error)
- func (c *Client) ListUsers(ctx context.Context) *UserList
- func (c *Client) ListUsersN(ctx context.Context, n int, pageToken string) ([]*User, string, error)
- func (c *Client) TokenFromRequest(req *http.Request) string
- func (c *Client) UpdateUser(ctx context.Context, user *User) error
- func (c *Client) UploadUsers(ctx context.Context, users []*User, algorithm string, ...) error
- func (c *Client) UserByEmail(ctx context.Context, email string) (*User, error)
- func (c *Client) UserByLocalID(ctx context.Context, localID string) (*User, error)
- func (c *Client) UserByToken(ctx context.Context, token string, audiences []string) (*User, error)
- func (c *Client) ValidateToken(ctx context.Context, token string, audiences []string) (*Token, error)
- type Config
- type DeleteAccountRequest
- type DeleteAccountResponse
- type DownloadAccountRequest
- type DownloadAccountResponse
- type GetAccountInfoRequest
- type GetAccountInfoResponse
- type GetOOBCodeRequest
- type GetOOBCodeResponse
- type GetProjectConfigResponse
- type IdpConfig
- type OOBCodeResponse
- type ProjectConfig
- type ProviderUserInfo
- type SetAccountInfoRequest
- type SetAccountInfoResponse
- type TimestampMilli
- type Token
- type UploadAccountRequest
- type UploadAccountResponse
- type UploadError
- type User
- type UserList
Constants ¶
const ( GET httpMethod = "GET" POST httpMethod = "POST" )
const ( ResetPasswordRequestType = "PASSWORD_RESET" ChangeEmailRequestType = "NEW_EMAIL_ACCEPT" VerifyEmailRequestType = "VERIFY_EMAIL" )
Request types accepted by identitytoolkit getOobConfirmationCode API.
const ( DefaultWidgetModeParamName = "mode" DefaultCookieName = "gtoken" )
const ( OOBActionParam = "action" OOBEmailParam = "email" OOBCAPTCHAChallengeParam = "challenge" OOBCAPTCHAResponseParam = "response" OOBOldEmailParam = "oldEmail" OOBNewEmailParam = "newEmail" OOBCodeParam = "oobCode" )
Parameter names used to extract the OOB code request.
const ( OOBActionChangeEmail = "changeEmail" OOBActionVerifyEmail = "verifyEmail" OOBActionResetPassword = "resetPassword" )
Acceptable OOB code request types.
Variables ¶
var ( APIBaseURI = "https://www.googleapis.com/identitytoolkit" APIVersion = "v3" APIPath = "relyingparty" )
Identitytoolkit API endpoint URL common parts.
var ( ErrMalformed = errors.New("malfored token") ErrInvalidAlgorithm = errors.New("invalid algorithm") ErrInvalidIssuer = errors.New("invalid issuer") ErrInvalidAudience = errors.New("invalid audience") ErrInvalidSignature = errors.New("invalid signature") ErrKeyNotFound = errors.New("key not found") ErrExpired = errors.New("token expired") ErrMissingAudience = errors.New("missing audiences for token validation") )
Errors that can be returned from the VerifyToken function.
Functions ¶
func ErrorResponse ¶
ErrorResponse generates a JSON error response from the given error.
func SuccessResponse ¶
func SuccessResponse() string
SuccessResponse generates a JSON response which indicates the request is processed successfully.
Types ¶
type APIClient ¶
An APIClient is an HTTP client that sends requests and receives responses from identitytoolkit APIs.
The underlying http.Client should add appropriate auth credentials according to the auth level of the API.
func (*APIClient) DeleteAccount ¶
func (c *APIClient) DeleteAccount(req *DeleteAccountRequest) (*DeleteAccountResponse, error)
DeleteAccount deletes an account.
func (*APIClient) DownloadAccount ¶
func (c *APIClient) DownloadAccount(req *DownloadAccountRequest) (*DownloadAccountResponse, error)
DownloadAccount donwloads accounts from identitytoolkit service.
func (*APIClient) GetAccountInfo ¶
func (c *APIClient) GetAccountInfo(req *GetAccountInfoRequest) (*GetAccountInfoResponse, error)
GetAccountInfo retreives the users' account information.
func (*APIClient) GetOOBCode ¶
func (c *APIClient) GetOOBCode(req *GetOOBCodeRequest) (*GetOOBCodeResponse, error)
GetOOBCode retrieves an OOB code.
func (*APIClient) GetProjectConfig ¶
func (c *APIClient) GetProjectConfig() (*GetProjectConfigResponse, error)
GetProjectConfig retrieves the configuration information for the project.
func (*APIClient) SetAccountInfo ¶
func (c *APIClient) SetAccountInfo(req *SetAccountInfoRequest) (*SetAccountInfoResponse, error)
SetAccountInfo updates the account information.
func (*APIClient) UploadAccount ¶
func (c *APIClient) UploadAccount(req *UploadAccountRequest) (*UploadAccountResponse, error)
UploadAccount uploads accounts to identitytoolkit service.
type Bytes ¶
type Bytes []byte
Bytes is a slice of bytes. It is URL safe Base64 instead of standard Base64 encoded when being marshalled to JSON.
func (Bytes) MarshalJSON ¶
MarshalJSON encodes the byte slice to a web safe base64 string.
func (*Bytes) UnmarshalJSON ¶
UnmarshalJSON decodes a web safe base64 string into a byte slice.
type Certificates ¶
type Certificates struct { URL string // Certificates URL. // contains filtered or unexported fields }
Certificates contains a set of availabe identitytoolkit public certificates which are indexed by key IDs ("kid"). It caches the certificates according to the HTTP response cache setting and refetches them upon cache expiring. It is safe to use a Certificates from multiple concurrent goroutines.
func (*Certificates) Cert ¶
func (c *Certificates) Cert(keyID string) (*x509.Certificate, error)
Cert returns the public certificate for the given key ID.
func (*Certificates) LoadIfNecessary ¶
func (c *Certificates) LoadIfNecessary(transport http.RoundTripper) error
LoadIfNecessary downloads the certificates if there are no cached ones or the cache expired.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client provides convenient utilities for integrating identitytoolkit service into a web service.
func (*Client) DeleteUser ¶
DeleteUser deletes a user specified by the local ID.
func (*Client) GenerateChangeEmailOOBCode ¶
func (c *Client) GenerateChangeEmailOOBCode( ctx context.Context, req *http.Request, email, newEmail, token string) (*OOBCodeResponse, error)
GenerateChangeEmailOOBCode generates an OOB code for changing email address.
If WidgetURL is not provided in the configuration, the OOBCodeURL field in the returned OOBCodeResponse is nil.
func (*Client) GenerateOOBCode ¶
GenerateOOBCode generates an OOB code based on the request.
func (*Client) GenerateResetPasswordOOBCode ¶
func (c *Client) GenerateResetPasswordOOBCode( ctx context.Context, req *http.Request, email, captchaChallenge, captchaResponse string) (*OOBCodeResponse, error)
GenerateResetPasswordOOBCode generates an OOB code for resetting password.
If WidgetURL is not provided in the configuration, the OOBCodeURL field in the returned OOBCodeResponse is nil.
func (*Client) GenerateVerifyEmailOOBCode ¶
func (c *Client) GenerateVerifyEmailOOBCode( ctx context.Context, req *http.Request, email string) (*OOBCodeResponse, error)
GenerateVerifyEmailOOBCode generates an OOB code for verifying email address.
If WidgetURL is not provided in the configuration, the OOBCodeURL field in the returned OOBCodeResponse is nil.
func (*Client) GetProjectConfig ¶
func (c *Client) GetProjectConfig(ctx context.Context) (*ProjectConfig, error)
GetProjectConfig gets the Gitkit configuration of this project.
func (*Client) ListUsers ¶
ListUsers lists all the users.
For example,
l := c.ListUsers() for { for u := range l.C { // Do something } if l.Error != nil { l.Retry() } else { break } }
func (*Client) ListUsersN ¶
ListUsersN lists the next n users. For the first n users, the pageToken should be empty. Upon success, the users and pageToken for next n users are returned.
func (*Client) TokenFromRequest ¶
TokenFromRequest extracts the ID token from the HTTP request if present.
func (*Client) UpdateUser ¶
UpdateUser updates the account information of the user.
func (*Client) UploadUsers ¶
func (c *Client) UploadUsers(ctx context.Context, users []*User, algorithm string, key, saltSeparator []byte) error
UploadUsers uploads the users to identitytoolkit service. algorithm, key, saltSeparator specify the password hash algorithm, signer key and separator between password and salt accordingly.
func (*Client) UserByEmail ¶
UserByEmail retrieves the account information of the user specified by the email address.
func (*Client) UserByLocalID ¶
UserByLocalID retrieves the account information of the user specified by the local ID.
func (*Client) UserByToken ¶
UserByToken retrieves the account information of the user specified by the ID token.
func (*Client) ValidateToken ¶
func (c *Client) ValidateToken(ctx context.Context, token string, audiences []string) (*Token, error)
ValidateToken validates the ID token and returns a Token.
Beside verifying the token is a valid JWT, it also validates that the token is not expired and is issued to the client with the given audiences.
type Config ¶
type Config struct { // WidgetURL is the identitytoolkit javascript widget URL. // It is used to generate the reset password or change email URL and // could be an absolute URL, an absolute path or a relative path. WidgetURL string `json:"widgetUrl,omitempty"` // WidgetModeParamName is the parameter name used by the javascript widget. // A default value is used if left unspecified. If the parameter name is set // to other value in the javascript widget, this field should be set to the // same value. WidgetModeParamName string `json:"widgetModeParamName,omitempty"` // CookieName is the name of the cookie that stores the ID token. CookieName string `json:"cookieName,omitempty"` // GoogleAppCredentialsPath is the path of the service account JSON key file // downloaded from Google cloud console. // Only specify it if you cannot use Google Application Default Credentials. // See https://developers.google.com/identity/protocols/application-default-credentials // for more details about Application Default Credentials. GoogleAppCredentialsPath string `json:"googleAppCredentialsPath",omitempty"` }
Config contains the configurations for creating a Client.
func LoadConfig ¶
LoadConfig loads the configuration from the config file specified by path.
type DeleteAccountRequest ¶
type DeleteAccountRequest struct {
LocalID string `json:"localId,omitempty"`
}
DeleteAccountRequest contains the user ID to be deleted.
type DeleteAccountResponse ¶
type DeleteAccountResponse struct { }
DeleteAccountResponse is the response for a DeleteAccountRequest upon success. It is an empty response.
type DownloadAccountRequest ¶
type DownloadAccountRequest struct { MaxResults int `json:"maxResults,omitempty"` NextPageToken string `json:"nextPageToken,omitempty"` }
DownloadAccountRequest contains the information for downloading accounts. MaxResults specifies the max number of accounts in one response. NextPageToken should be empty for the first request and the value from the previous response afterwards.
type DownloadAccountResponse ¶
type DownloadAccountResponse struct { Users []*User `json:"users,omitempty"` NextPageToken string `json:"nextPageToken,omitempty"` }
DownloadAccountResponse contains the downloaded accounts and the page token for next request.
type GetAccountInfoRequest ¶
type GetAccountInfoRequest struct { Emails []string `json:"email,omitempty"` LocalIDs []string `json:"localId,omitempty"` }
GetAccountInfoRequest contains the email addresses or user IDs which are used to retrieve the user account information.
type GetAccountInfoResponse ¶
type GetAccountInfoResponse struct {
Users []*User `json:"users,omitempty"`
}
GetAccountInfoResponse contains the user account information specified by the corresponding GetAccountInfoRequest upon success.
type GetOOBCodeRequest ¶
type GetOOBCodeRequest struct { RequestType string `json:"requestType,omitempty"` Email string `json:"email,omitempty"` CAPTCHAChallenge string `json:"challenge,omitempty"` CAPTCHAResponse string `json:"captchaResp,omitempty"` NewEmail string `json:"newEmail,omitempty"` Token string `json:"idToken,omitempty"` UserIP string `json:"userIp,omitempty"` }
GetOOBCodeRequest contains the information to get an OOB code from identitytoolkit service.
There are three kinds of OOB code:
1. OOB code for password recovery. The RequestType should be PASSWORD_RESET and Email, CAPTCHAChallenge and CAPTCHAResponse are required.
2. OOB code for email change. The RequestType should be NEW_EMAIL_ACCEPT and Email, newEmail and Token are required.
3. OOB code for email verification. The RequestType should be VERIFY_EMAIL and Email is required.
type GetOOBCodeResponse ¶
type GetOOBCodeResponse struct {
OOBCode string `json:"oobCode,omitempty"`
}
GetOOBCodeResponse contains the OOB code upon success.
type GetProjectConfigResponse ¶
type GetProjectConfigResponse struct { ProjectID string `json:"projectId,omitempty"` APIKey string `json:"apiKey,omitempty"` AllowPasswordUser bool `json:"allowPasswordUser,omitempty"` IdpConfigs []*IdpConfig `json:"idpConfig,omitempty"` }
GetProjectConfigResponse contains the project ID, API key, whether password login is enabled and a list of IDP configs.
type IdpConfig ¶
type IdpConfig struct { Provider string `json:"provider,omitempty"` Enabled bool `json:"enabled,omitempty"` ClientID string `json:"clientId,omitempty"` }
IdpConfig holds the IDP configuration.
type OOBCodeResponse ¶
type OOBCodeResponse struct { // Action identifies the request type. Action string // The email address of the user. Email string // The new email address of the user. // This field is only populated when Action is OOBActionChangeEmail. NewEmail string // The OOB confirmation code. OOBCode string // The URL that contains the OOB code and can be sent to the user for // confirming the action, e.g., sending the URL to the email address and // the user can click the URL to continue to reset the password. // It can be nil if WidgetURL is not provided in the configuration. OOBCodeURL *url.URL }
OOBCodeResponse wraps the OOB code response.
type ProjectConfig ¶
type ProjectConfig struct { // BrowserAPIKey is the API key used to call Google API in web browser. BrowserAPIKey string `json:"browserApiKey,omitempty"` // ClientID is the Google OAuth2 client ID for the server. ClientID string `json:"clientId,omitempty"` // SignInOptions are the sign in methods provided to users for sign in. SignInOptions []string `json:"signInOptions,omitempty"` }
ProjectConfig contains the Gitkit configurations of the project.
type ProviderUserInfo ¶
type ProviderUserInfo struct { // ProviderID is the identifer for the IDP, usually the TLD, e.g., google.com. ProviderID string `json:"providerId,omitempty"` // FederatedID is a unique identifier for the user within the IDP. FederatedID string `json:"federatedId,omitempty"` // DisplayName is the name of the user at the IDP. DisplayName string `json:"displayName,omitempty"` // PhotoURL is the profile picture URL of the user at the IDP. PhotoURL string `json:"photoUrl,omitempty"` }
ProviderUserInfo holds the user information from an identity provider (IDP).
type SetAccountInfoRequest ¶
type SetAccountInfoRequest struct { LocalID string `json:"localId,omitempty"` Email string `json:"email,omitempty"` DisplayName string `json:"displayName,omitempty"` Password string `json:"password,omitempty"` EmailVerified bool `json:"emailVerified,omitempty"` }
SetAccountInfoRequest contains account information to update. Either LocalID or Email should be provided to find the account. The Password field contains the new raw password if provided.
type SetAccountInfoResponse ¶
type SetAccountInfoResponse struct { }
SetAccountInfoResponse is the response for a SetAccountInfoRequest upon success. It is an empty response.
type TimestampMilli ¶
type TimestampMilli float64
TimestampMilli represents the Unix time in milliseconds. float64 is used here as the underlying type because the API returns a float.
func (TimestampMilli) AsTime ¶
func (t TimestampMilli) AsTime() time.Time
AsTime converts the TimestampMilli into a time.Time.
func (TimestampMilli) String ¶
func (t TimestampMilli) String() string
String implements the fmt.Stringer interface.
type Token ¶
type Token struct { // Issuer identifies the issuer of the ID token. Issuer string // Audience identifies the client that this ID token is intended for. Audience string // IssueAt is the time at which this ID token was issued. IssueAt time.Time // ExpireAt is the expiration time on or after which the ID token must not // be accepted for processing. ExpireAt time.Time // LocalID is the locally unique identifier within the client for the user. LocalID string // Email is the email address of the user. Email string // EmailVerified indicates whether or not the email address of the user has // been verifed. EmailVerified bool // ProviderID is the identifier for the identity provider (IDP) for the // user. It is usually the top level domain of the IDP, e.g., google.com. ProviderID string // DisplayName is the name that the user wants to be referred to. DisplayName string // PhotoURL is the URL of the user's profile picture. PhotoURL string // The token string. TokenString string }
Token is a verified ID token issued by identitytoolkit service. See http://openid.net/specs/openid-connect-core-1_0.html#IDToken for more information about ID token.
func VerifyToken ¶
func VerifyToken(token string, audiences []string, issuers []string, certs *Certificates) (*Token, error)
VerifyToken verifies the JWT is valid and signed by identitytoolkit service and returns the verfied token. A token is valid if and only if it passes the following checks: 1. The value of "iss" field is one of the issuers if issuers is not nil; 2. The value of "aud" field is the same as the audience; 3. The token is not expired according to the "exp" field; 4. The signature can be verified from one of the certs;
type UploadAccountRequest ¶
type UploadAccountRequest struct { Users []*User `json:"users,omitempty"` HashAlgorithm string `json:"hashAlgorithm,omitempty"` SignerKey Bytes `json:"signerKey,omitempty"` SaltSeparator Bytes `json:"saltSeparator,omitempty"` }
UploadAccountRequest the account information of users to upload. The hash algorithm and signer key for the password are required.
type UploadAccountResponse ¶
type UploadAccountResponse struct {
Error UploadError `json:"error,omitempty"`
}
UploadAccountResponse contains the error information if some accounts are failed to upload.
type UploadError ¶
type UploadError []*struct { // Index indicates the index of the failed account. Index int `json:"index,omitempty"` // Message is the uploading error message for the failed account. Message string `json:"message,omitempty"` }
UploadError is the error object for partial upload failure.
type User ¶
type User struct { // LocalID is the locally unique identifier for the user. LocalID string `json:"localId,omitempty"` // Email is the email address of the user. Email string `json:"email,omitempty"` // EmailVerified indicates if the email address of the user has been verifed. EmailVerified bool `json:"emailVerified,omitempty"` // DisplayName is the current name of the user. For instance, if the user // currently signs in with Google, the DisplayName is the one from Google IDP. DisplayName string `json:"displayName,omitempty"` // PhotoURL is the current profile picture URL of the user. For instance, if the // user currently signs in with Google, the PhotoURL is the one from Google IDP. PhotoURL string `json:"photoUrl,omitempty"` // ProviderUserInfo holds user information from all IDPs. ProviderUserInfo []ProviderUserInfo `json:"providerUserInfo,omitempty"` // PasswordHash is the hashed user password. PasswordHash Bytes `json:"passwordHash,omitempty"` // PasswordUpdateAt is the Unix time in milliseconds of the last password update. PasswordUpdateAt TimestampMilli `json:"passwordUpdateAt,omitempty"` // Salt is the salt used for hashing password. Salt Bytes `json:"salt,omitempty"` // ProviderID, if present, indicates the IDP with which the user signs in. ProviderID string `json:"providerId,omitempty"` // Password is the raw password of the user. It is only used to set new password. Password string `json:"-"` }
User holds the user account information.