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, LoginCompleteRedirectURI: "/main.html", LogoutCompleteRedirectURI: "/", }) 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 ( // DefaultHost is the Connect ID production host. We recommend using this. DefaultHost = "connect.telenordigital.com" // StagingHost is the host name for the staging (aka testing) environment StagingHost = "connect.staging.telenordigital.com" )
const ( DefaultScopes = "openid profile email phone" DefaultLoginInit = "login" DefaultLogoutInit = "logout" DefaultLoginRedirectURI = "http://localhost:8080/connect/oauth2callback" DefaultLogoutRedirectURI = "http://localhost:8080/connect/logoutcallback" DefaultLoginRedirect = "oauth2callback" DefaultLogoutRedirect = "logoutcallback" DefaultLoginCompleteRedirectURI = "/" DefaultLogoutCompleteRedirectURI = "/" DefaultProfileEndpoint = "profile" )
These constants provide default values for ClientConfig.
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 ¶
var SQLSchema = []string{
`CREATE TABLE IF NOT EXISTS sessions (
session_id VARCHAR(128) NOT NULL,
session_data TEXT,
expires BIGINT NOT NULL,
CONSTRAINT sessions_pk PRIMARY KEY (session_id))`,
"CREATE INDEX IF NOT EXISTS sessions_expired ON sessions(expires)",
`CREATE TABLE IF NOT EXISTS nonces (
nonce VARCHAR(128) NOT NULL,
created BIGINT NOT NULL,
type SMALLINT NOT NULL,
CONSTRAINT nonces_pk PRIMARY KEY (nonce))`,
"CREATE INDEX IF NOT EXISTS nonces_created ON nonces(created)",
"CREATE INDEX IF NOT EXISTS nonces_type ON nonces(type)",
}
SQLSchema contains DDL statements for the backend store. The statements works on both SQLite and PostgreSQL. They must be executed in the order they are returned.
Functions ¶
func HasSessionCookie ¶ added in v0.7.0
HasSessionCookie returns true if the request contains a CONNECT ID session cookie
func SQLStorePrepare ¶ added in v0.7.0
SQLStorePrepare runs the DDL statements on the database.
Types ¶
type ClientConfig ¶
type ClientConfig struct { Host string // Host is the name of the Connect ID host to use. Scopes string // Scopes is a space separated list of the OAuth scopes to use when logging in. ClientID string // ClientID is the OAuth client ID. Password string // Password is the (optional) secret. LoginInit string // LoginInit is the endpoint for starting a login. LogoutInit string // LogoutInit is the endpoint for starting a logout. LoginRedirectURI string // LoginRedirectURI is where the OAuth server redirects after a successful login. LogoutRedirectURI string // LogoutRedirectURI is where the OAuth server redirects after a successful logout. LoginRedirect string // LoginRedirect is the endpoint that serves - and is thus typically a suffix of - LoginRedirectURI. LogoutRedirect string // LogoutRedirect is the endpoint that serves - and is thus typically a suffix of - LogoutRedirectURI. LoginCompleteRedirectURI string // LoginCompleteRedirectURI is where goconnect redirects after a successful login. LogoutCompleteRedirectURI string // LogoutCompleteRedirectURI is where goconnect redirects after a successfull logout. ProfileEndpoint string // ProfileEndpoint is the session profile information endpoint. UseSecureCookie bool // UseSecureCookie indicates whether to use a secure cookie. }
ClientConfig holds the ConnectID configuration.
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", LoginCompleteRedirectURI: "/main.html", LogoutCompleteRedirectURI: "/", }) fmt.Println(config.LoginCompleteRedirectURI) fmt.Println(config.LogoutCompleteRedirectURI)
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 usign the default (memory-based) storage.
func NewConnectIDWithStorage ¶ added in v0.7.0
func NewConnectIDWithStorage(config ClientConfig, storage Storage) *GoConnect
NewConnectIDWithStorage creates a new ConnectID client with the specified storage implementation.
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.LoginRedirect for the OAuth redirect when login is complete Config.LogoutInit to start a logout roundtrip towards the OAuth server Config.LogoutRedirect for the OAuth redirect when logout is complete
The Init endpoints are the ones you navigate to to initiate the action. The Redirect 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) //UpdateSession updates a session in the backend store UpdateSession(Session) error // ListSessions lists all of the sessions in the backend store. ListSessions() ([]Session, error) // RemoveExpiredNonces removes all of the expired nonces from the store RemoveExpiredNonces() }
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.