Documentation ¶
Overview ¶
Package goconnect is an authentication library for the Telenor CONNECT ID service.
The go-connectid library is an easy-to-use library when you want to integrate with the Telenor CONNECT ID service. It can be retrofitted to any http service that uses the http package with a few simple changes in the service setup.
Creating a new client ¶
Start by creating a new client configuration and Connect client:
config := connect.NewDefaultConfig(ClientConfig{ Host: connect.StagingHost, ClientID: username, Password: password, LoginCompleteRedirect: "/main.html", LogoutCompleteRedirect: "/", }) connectid := connect.NewConnectID(config)
Setting up the HTTP mux ¶
Once the client is created you can wrap the http.Handler and http.HandlerFunc elements in your server:
// This the default start page. It uses the unwrapped handler since it // won't require authentication http.HandleFunc("/", startPageHandler) // This page will require authentication http.HandleFunc("/main.html", connectid.NewAuthHandlerFunc(mainPageHandler)) // Protected resources requires authentication http.Handle("/extra/", connectid.NewAuthHandler( http.StripPrefix("/extra/", http.FileServer(http.Dir("html/extra"))))) // API endpoint - requires authentication http.HandleFunc("/api/oneliner", connectid.NewAuthHandlerFunc(api.OneLinerHandlerFunc))
The session object is stored into the http.Request context. Retrieve the context with the SessionContext key:
// Write the logged in user's name func myHandlerFunc(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Header().Set("Content-Type", "text/plain") session := r.Context().Value(connect.SessionContext) w.Write([]byte("Hello, ", session.Name)) }
The callbacks for the OAuth service must be set up according to your configuration.
The default development client is set up to redirect to http://localhost:8080/connect/complete and http://localhost:8080/connect/login and the Go-Connect handler is set up the following way:
http.Handle("/connect/", connectid.Handler())
Index ¶
Examples ¶
Constants ¶
const ( // StagingHost is the host name for the staging (aka testing) environment StagingHost = "connect.staging.telenordigital.com" // DefaultHost is the Connect ID production host. We recommend using this. DefaultHost = "connect.telenordigital.com" )
const ( // DefaultLoginRedirect is the default location the browser is redirected to // after the login has completed. DefaultLoginRedirect = "/" // DefaultLogoutRedirect is the default location the browser is redirected // to after the logout has completed DefaultLogoutRedirect = "/" // DefaultScopes are the scopes that will be requested when logging in DefaultScopes = "openid profile email phone" // DefaultLoginRedirectURI is the default redirect url for login. DefaultLoginRedirectURI = "http://localhost:8080/connect/oauth2callback" // DefaultLogoutRedirectURI is the default redirect url for logout. DefaultLogoutRedirectURI = "http://localhost:8080/connect/logoutcallback" // DefaultLoginCallback is the name of the endpoint that the CONNECT ID // OAuth server redirects to when a login roundtrip is completed DefaultLoginCallback = "oauth2callback" // DefaultLogoutCallback is the name of the endpoint that the CONNECT ID // OAuth server redirects to when a logout roundtrip is completed DefaultLogoutCallback = "logoutcallback" // DefaultLoginInit is the name of the endpoint the client accesses to // start a login roundtrip to the OAuth server DefaultLoginInit = "login" // DefaultLogoutInit is the name of the endpoint the client accesses to // start a logout roundtrip to the OAuth server DefaultLogoutInit = "logout" // DefaultProfileEndpoint is the name of the endpoint the client uses to access // session profile information. DefaultProfileEndpoint = "profile" )
const ( // SessionContext is the identifier for the http.Request context. Use this to access the // session object when the NewHandlerFunc has wrapped a HandlerFunc. SessionContext contextKey = "connect-session" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ClientConfig ¶
type ClientConfig struct { Host string // Host is the hostname of the Connect ID host to use. Scopes string // Scopes is the OAuth scopes to use when logging in. LogoutRedirectURI string // LogoutRedirectURI is the redirect URI for completed logins. LoginRedirectURI string // LoginRedirectURI is the redirect URI for completed logouts. ClientID string // ClientID is the OAuth client ID. Password string // Password is the (optional) secret. LoginCompleteRedirect string // LoginCompleteRedirect is where the client is redirected after a successful login roundtrip. LogoutCompleteRedirect string // LogoutCompleteRedirect is where the client is redirected after a logout. LoginCallback string // Name for endpoint that receives login callback LogoutCallback string // Name for endpoint that receives logout callback LoginInit string // Name for endpoint that starts a login roundtrip LogoutInit string // Name for endpoint that starts a logout roundtrip ProfileEndpoint string // Name for session profile information endpoint UseSecureCookie bool // Secure flag for cookie }
ClientConfig holds the ConnectID configuration. This is only used internally
func NewDefaultConfig ¶
func NewDefaultConfig(overrides ClientConfig) ClientConfig
NewDefaultConfig creates a configuration with default values prepopulated. If the parameter is set in the overrides parameter it won't be set.
Example ¶
config := NewDefaultConfig(ClientConfig{ Host: StagingHost, ClientID: "client-id", Password: "client-secret", LoginCompleteRedirect: "/main.html", LogoutCompleteRedirect: "/", }) fmt.Println(config.LoginCompleteRedirect) fmt.Println(config.LogoutCompleteRedirect)
Output: /main.html /
type GoConnect ¶
type GoConnect struct { Config ClientConfig // contains filtered or unexported fields }
GoConnect is the main entry point to Telenor CONNECT ID client API.
func NewConnectID ¶
func NewConnectID(config ClientConfig) *GoConnect
NewConnectID creates a new ConnectID client.
func (*GoConnect) Handler ¶
Handler returns a http.Handler that will respond on the following endpoints:
Config.LoginInit to start a login roundtrip towards the OAuth server Config.LoginCallback for the OAuth callback when login is complete Config.LogoutInit to log out the currently logged in user Config.LogoutCallback for the OAuth callback when logout is complete
The Init endpoints are the ones you navigate to to initiate the action. The Callback endpoints are redirected to from the OAuth server when it is complete.
func (*GoConnect) NewAuthHandler ¶
NewAuthHandler returns a http.Handler that requires authentication. If the request isn't authenticated a 401 Unauthorized is returned to the client, otherwise the existing http.Handler is invoked. The Session object is passed along in the request's Context.
func (*GoConnect) NewAuthHandlerFunc ¶
func (t *GoConnect) NewAuthHandlerFunc(existingFunc http.HandlerFunc) http.HandlerFunc
NewAuthHandlerFunc returns a http.HandlerFunc that requires authentication. If the request isn't authenticated a 401 Unauthorized is returned, otherwise the existing http.HandlerFunc will be called as normal. The session object is passed along in the request's Context object.
func (*GoConnect) SessionProfile ¶
func (t *GoConnect) SessionProfile(w http.ResponseWriter, r *http.Request)
SessionProfile is a premade session endpoint that you can use to serve the profile information to the end user. Since this resource might be used by JavaScript clients it would potentially need CORS headers and a matching OPTIONS header but this might introduce security issues. Add the header to the default mux by using the following snippet:
http.HandleFunc("/connect/profile", connect.SessionProfile)
type Session ¶
type Session struct { UserID string `json:"connect_id"` // Connect ID Name string `json:"name"` // Name (might be blank) Locale string `json:"locale"` // Locale (might be blank) Email string `json:"email"` // Email (might be blank) VerifiedEmail bool `json:"verified_email"` // Email is verified Phone string `json:"phone"` // Phone # (might be blank) VerifiedPhone bool `json:"verified_phone"` // Verified phone // contains filtered or unexported fields }
Session holds the session information from the CONNECT ID OAuth server.
type Storage ¶
type Storage interface { // Add state nonce to storage. This is disposable and will expire in 20 minutes PutLoginNonce(token string) error // Retrieve and remove nonce (if it exists) from storage CheckLoginNonce(token string) error // Add state nonce to storage. This is disposable and will expire in 20 minutes PutLogoutNonce(token string) error // Retrieve and remove nonce (if it exists) from storage CheckLogoutNonce(token string) error // PutSession creates a new session identifier and stores // the information in a session structure PutSession(session *Session) error // GetSession returns the session associated with the session ID. GetSession(sessionid string) (*Session, error) // DeleteSession removes the session DeleteSession(sessionid string) // RefreshTokens does a token refresh on all tokens that are about to // expire. If the token fails to refresh the session will be invalidated. RefreshTokens(config ClientConfig, lookahead time.Duration) }
Storage is the session and nonce storage used by the go-connectid client. The default session and nonce storage is memory-based. It works perfectly fine for a single-server installation but if you run more than one server you probably want to use a different backend such as Memcached or Redis for session storage.
The storage implementation is responsible for expiring nonces automatically. RefreshTokens is used to refresh access tokens against the OAuth server.
func NewMemoryStorage ¶
func NewMemoryStorage() Storage
NewMemoryStorage creates a new memory-backed storage implementation. This implementation is suitable for single-server solution. If you are running on more than one server this must be implemented as a common storage, ie. in some sort of database. The stored data is just nonces and sessions so data integrity isn't the most critical aspect. A storage backed by Memcached or Redis would be ideal for this.