apple

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 26, 2021 License: GPL-3.0 Imports: 11 Imported by: 0

README

apple-auth-go

GoDoc Build Status Build Status

apple-auth-go is a unofficial Golang package to validate authorization tokens and manage the authorization of Apple Sign In server side. It provides utility functions and models to retrieve user information and validate authorization codes.

Installation

Install with go modules:

go get github.com/GianOrtiz/apple-auth-go

Usage

The package follow the Go approach to resolve problems, the usage is pretty straightforward, you start initiating a client with:

package main

import (
    "github.com/GianOrtiz/apple-auth-go"
)

func main() {
    appleAuth, err := apple.New("<APP-ID>", "<TEAM-ID>", "<KEY-ID>", "/path/to/apple-sign-in-key.p8")
    if err != nil {
        panic(err)
    }
}

To validate an authorization code, retrieving refresh and access tokens:

package main

import (
    "github.com/GianOrtiz/apple-auth-go"
)

func main() {
    appleAuth, err := apple.New("<APP-ID>", "<TEAM-ID>", "<KEY-ID>", "/path/to/apple-sign-in-key.p8")
    if err != nil {
        panic(err)
    }

    // Validate authorization code from a mobile app.
    tokenResponse, err := appleAuth.ValidateCode("<AUTHORIZATION-CODE>")
    if err != nil {
        panic(err)
    }

    // Validate authorization code from web app with redirect uri.
    tokenResponse, err := appleAuth.ValidateCodeWithRedirectURI("<AUTHORIZATION-CODE>", "https://redirect-uri")
    if err != nil {
        panic(err)
    }
}

The returned tokenResponse provides the access token, to make requests on behalf of the user with Apple servers, the refresh token, to retrieve a new access token after expiration, trought the ValidateRefreshToken method, and the id token, which is a JWT encoded string with user information. To retrieve the user information from this id token we provide a utility function GetUserInfoFromIDToken:

package main

import (
    "fmt"

    "github.com/GianOrtiz/apple-auth-go"
)

func main() {
    appleAuth, err := apple.New("<APP-ID>", "<TEAM-ID>", "<KEY-ID>", "/path/to/apple-sign-in-key.p8")
    if err != nil {
        panic(err)
    }

    // Validate authorization code from a mobile app.
    tokenResponse, err := appleAuth.ValidateCode("<AUTHORIZATION-CODE>")
    if err != nil {
        panic(err)
    }

    user, err := apple.GetUserInfoFromIDToken(tokenResponse.idToken)
    if err != nil {
        panic(err)
    }

    // User Apple unique identification.
    fmt.Println(user.UID)
    // User email if the user provided it.
    fmt.Println(user.Email)
}

Documentation

Overview

Package apple handles the validation and authentication with Apple servers for Apple Sign In token validations.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrorResponseTypeInvalidRequest the request is malformed, typically
	// because it is missing a parameter, contains an unsupported parameter,
	// includes multiple credentials, or uses more than one mechanism for
	// authenticating the client.
	ErrorResponseTypeInvalidRequest ErrorResponseType = "invalid_request"

	// ErrorResponseTypeInvalidClient the client authentication failed,
	// typically due to a mismatched or invalid client identifier, invalid
	// client secret (expired token, malformed claims, or invalid signature), or
	// mismatched or invalid redirect URI.
	ErrorResponseTypeInvalidClient ErrorResponseType = "invalid_client"

	// ErrorResponseTypeInvalidGrant the authorization grant or refresh token
	// is invalid, typically due to a mismatched or invalid client identifier,
	// invalid code (expired or previously used authorization code), or invalid
	// refresh token.
	ErrorResponseTypeInvalidGrant ErrorResponseType = "invalid_grant"

	// ErrorResponseTypeUnauthorizedClient the client is not authorized to use
	// this authorization grant type.
	ErrorResponseTypeUnauthorizedClient ErrorResponseType = "unauthorized_client"

	// ErrorResponseTypeUnsupportedGrantType the authenticated client is not
	// authorized to use this grant type.
	ErrorResponseTypeUnsupportedGrantType ErrorResponseType = "unsupported_grant_type"

	// ErrorResponseTypeInvalidScope the requested scope is invalid.
	ErrorResponseTypeInvalidScope ErrorResponseType = "invalid_scope"

	// ErrorResponseInvalidRequest error when the response is invalid_request. Check message.
	ErrorResponseInvalidRequest = ErrorResponse{
		Type:    ErrorResponseTypeInvalidRequest,
		Message: "The request is malformed, typically because it is missing a parameter, contains an unsupported parameter, includes multiple credentials, or uses more than one mechanism for authenticating the client.",
	}

	// ErrorResponseInvalidClient error when the response is invalid_client. Check message.
	ErrorResponseInvalidClient = ErrorResponse{
		Type:    ErrorResponseTypeInvalidClient,
		Message: "The client authentication failed, typically due to a mismatched or invalid client identifier, invalid client secret (expired token, malformed claims, or invalid signature), or mismatched or invalid redirect URI.",
	}

	// ErrorResponseInvalidGrant error when the response is invalid_grant. Check message.
	ErrorResponseInvalidGrant = ErrorResponse{
		Type:    ErrorResponseTypeInvalidGrant,
		Message: "The authorization grant or refresh token is invalid, typically due to a mismatched or invalid client identifier, invalid code (expired or previously used authorization code), or invalid refresh token.",
	}

	// ErrorResponseUnauthorizedClient error when the response is unauthorized_client. Check message.
	ErrorResponseUnauthorizedClient = ErrorResponse{
		Type:    ErrorResponseTypeUnauthorizedClient,
		Message: "The client is not authorized to use this authorization grant type.",
	}

	// ErrorResponseUnsupportedGrantType error when the response is unsupported_grant_type. Check message.
	ErrorResponseUnsupportedGrantType = ErrorResponse{
		Type:    ErrorResponseTypeUnsupportedGrantType,
		Message: "the authenticated client is not authorized to use this grant type.",
	}

	// ErrorResponseInvalidScope error when the response is invalid_scope. Check message.
	ErrorResponseInvalidScope = ErrorResponse{
		Type:    ErrorResponseTypeInvalidScope,
		Message: "The requested scope is invalid.",
	}
)

Functions

func New

func New(appID, teamID, keyID, keyPath string) (*appleAuth, error)

Setup and return a new AppleAuth for validation of tokens.

Types

type AppleAuth

type AppleAuth interface {
	// ValidateCode validates an authorization code returning refresh token,
	// access token and token id.
	ValidateCode(code string) (*TokenResponse, error)

	// ValidateCode validates an authorization code with a redirect uri returning
	// refresh token, access token and token id.
	ValidateCodeWithRedirectURI(code, redirectURI string) (*TokenResponse, error)

	// ValidateRefreshToken validates a refresh token returning refresh token, access
	// token and token id.
	ValidateRefreshToken(refreshToken string) (*TokenResponse, error)
}

AppleAuth is the contract for communication and validation of Apple user tokens.

type AppleUser

type AppleUser struct {
	// UID Apple unique identification for the user.
	UID string `json:"uid"`

	// Email Apple user email.
	Email string `json:"email"`

	// EmailVerified whether the email is verified.
	EmailVerified bool `json:"email_verified"`

	// IsPrivateEmail whether the email shared by the user is the proxy address.
	IsPrivateEmail bool `json:"is_private_email"`

	// RealUserStatus an integer value that indicates whether the user appears
	// to be a real person.
	RealUserStatus RealUserStatus `json:"real_user_status"`
}

AppleUser is the model to hold information about the user.

func GetUserInfoFromIDToken

func GetUserInfoFromIDToken(idToken string) (*AppleUser, error)

GetUserInfoFromIDToken retrieve the user info from the JWT id token.

type ErrorResponse

type ErrorResponse struct {
	Type    ErrorResponseType
	Message string
}

func (ErrorResponse) Error

func (e ErrorResponse) Error() string

Error implements the error interface.

type ErrorResponseType

type ErrorResponseType string

type RealUserStatus

type RealUserStatus int

RealUserStatus an integer value that indicates whether the user appears to be a real person.

var (
	// RealUserStatusUnsupported unsupported, only works in iOS >= 14.
	RealUserStatusUnsupported RealUserStatus = 0
	// RealUserStatusUnknown cannot determine if the user is real.
	RealUserStatusUnknown RealUserStatus = 1
	// RealUserStatusLikelyReal user is likely real.
	RealUserStatusLikelyReal RealUserStatus = 2
)

type TokenResponse

type TokenResponse struct {
	// AccessToken (Reserved for future use) A token used to access allowed data.
	// Currently, no data set has been defined for access.
	AccessToken string `json:"access_token"`
	// ExpiresIn the amount of time, in seconds, before the access token expires.
	ExpiresIn int `json:"expires_in"`
	// IDToken a JSON Web Token that contains the user’s identity information.
	IDToken string `json:"id_token"`
	// RefreshToken The refresh token used to regenerate new access tokens.
	// Store this token securely on your server.
	RefreshToken string `json:"refresh_token"`
	// TokenType the type of access token.
	TokenType string `json:"token_type"`
}

TokenResponse response when validation was successfull.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL