Authentication and tokens
Complete Ring's two-factor login flow, then pass account credentials with each request.
go-ring does not keep an account's access token or refresh token on the
shared Client. Create an isolated login session for the initial OAuth and
two-factor exchange, save the returned tokens securely, and pass an
AuthContext to each account operation.
Ring authentication does not support browser CORS. Run this flow in a trusted backend, never in browser JavaScript.
Complete the two-factor flow
Use the same LoginSession to request a verification code and submit it. The
session retains the OAuth state, cookies, and PKCE verifier needed to finish
that exchange.
login, err := client.NewLoginSession(ring.LoginSessionRequest{
Username: username,
Password: password,
})
if err != nil {
return err
}
defer login.Close()
if err := login.Request2FACode(ctx); err != nil {
return err
}
tokens, err := login.Authenticate(ctx, ring.CompleteLoginRequest{OTPCode: otpCode})
if err != nil {
return err
}
auth := ring.AuthContext{
AccessToken: tokens.AccessToken,
HardwareID: login.HardwareID(),
}Store the complete token response, including the refresh token and the hardware ID. Restrict access to the stored secrets and never log credentials, verification codes, or tokens.
If you omit HardwareID when opening the login session, save the generated
login.HardwareID() with its tokens. Keep one hardware ID per account
installation. Avoid requesting multiple verification codes: Ring can rate-limit
their delivery.
Use and refresh tokens
Pass the account context with each request. A single Client can serve more
than one account because authentication is supplied per operation.
devices, err := client.ListDevices(ctx, ring.ListDevicesRequest{Auth: auth})
if err != nil {
return err
}Refresh tokens rotate. Replace the stored response after every successful refresh:
tokens, err := client.RefreshToken(ctx, ring.RefreshTokenRequest{
RefreshToken: stored.RefreshToken,
HardwareID: hardwareID,
})
if err != nil {
return err
}
// Persist the complete tokens response before discarding the old one.For the full authentication example, see
examples/token-exchange.
Wire contract: OAuth token exchange.
Authentication, rate-limit, and token failures return typed errors. Check the class before choosing whether to retry or ask the user to log in again:
if err != nil {
switch {
case ringapimodels.IsRateLimitError(err):
// Delay according to your retry policy.
return err
case ringapimodels.IsTokenError(err):
// Renew or replace the caller-owned credentials.
return err
default:
return err
}
}ringapimodels also exposes IsUnauthorizedError, IsNotFoundError,
IsConnectionError, and IsHTTPStatusCode. Avoid logging response bodies that
may contain account details.