Member authentication

In order to make use of a Loyalty session, a loyaltySessionToken must be generated as part of member authentication.

Note: in endpoints that return an access_token property, the access_token property is the same as the loyaltySessionToken.

There are currently two different methods available in the API for authenticating a member:

  • Token Auth - A new authentication system using JWT tokens that enables refreshable tokens to be used on all endpoints and is not tied directly to a userSessionId.
  • Legacy Auth - The original authentication of the API has a single ValidateMember endpoint that handles credential validation and linking the authenticated member to a userSessionId.

The following grid describes the credentials supported by the two authentication systems:

Auth Credentials Required Parameters Token Auth Legacy Auth
Username and Password MemberLogin
MemberPassword
Email and Password MemberEmail
MemberPassword
Card Number and PIN Number MemberCardNumber
PinNumber
Card Number MemberCardNumber
Member ID MemberId
External Issuer (e.g. Facebook) n/a
  • Note: special security exceptions must be made in configuration to allow clients to authenticate with insecure credentials such as card number or member ID with and without a PIN.

Authentication using tokens

In version 5.0.3 of Connect (and Loyalty), authentication using JWT tokens was enabled and is currently the preferred method for authentication.

To begin, an authentication token must be generated via one of the authentication endpoints:

Once the token has been generated, it can be provided to all future calls to Connect as a Loyalty session token to enable Loyalty-specific features.

Authentication with Loyalty credentials

The following example uses standard username and password credentials stored in Loyalty for authentication.

POST: /loyalty/auth/authenticate-by-username-password

Request:

{
  "username": "myusername",
  "password": "mypassword"
}

Response:

{
    "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6I...",
    "token_type": "bearer",
    "expires_in": 899,
    "refresh_token": "d1af6381fd6043e48a735e283fa8345b"
}

Inspecting the JWT returned in the access_token property provides basic user information.

{
  "sub": "1Y8BR0MVWGN",
  "unique_name": "1Y8BR0MVWGN",
  "loyalty_membership_id": "1Y8BR0MVWGN",
  "given_name": "Rick",
  "family_name": "Sanchez",
  "vista_loyalty_membership_id": "1Y8BR0MVWGN",
  "nbf": 1537850382,
  "exp": 1537851282,
  "iat": 1537850382,
  "iss": "Vista.Authentication.LoyaltyMember",
  "aud": "all"
}

For full member details, the GetMember endpoint should be called with the returned access_token.

Authentication via external issuers

In addition to using the credentials stored within Loyalty, Connect can authenticate with any external issuer providing the issuer is linked with a member in Loyalty.

External issuers are configured as a plugin system so options available will vary per environment.

To get a list of currently supported external issuers, the ExternalIssuers endpoint can be used.

GET: /loyalty/auth/external-issuers

{
    "activeIssuers": [
        "Facebook",
        "Google"
    ]
}

Once authentication has been made by the external issuer, the resultant user token can be provided to Connect via the AuthenticateByExternalToken endpoint.

POST: /loyalty/auth/authenticate-by-external-token

Request:

{
  "issuerName": "Facebook",
  "token": "myfacebookusertoken"
}

Response:

{
    "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6I...",
    "token_type": "bearer",
    "expires_in": 899,
    "refresh_token": "d1af6381fd6043e48a735e283fa8345b"
}

Linking external issuers to existing Loyalty accounts

To link an existing Loyalty member to an external issuer account:

  • Generate a loyaltySessionToken via the AuthenticateByExternalToken endpoint.
  • Call the ValidateMember endpoint using Vista credentials.
  • Pass the loyaltySessionToken to UpdateMember which will make the link.

Linking external issuers to new Loyalty accounts (free)

To link a new Loyalty member on a free membership tier to an external issuer account:

  • Generate a loyaltySessionToken via the AuthenticateByExternalToken endpoint.
  • Pass the loyaltySessionToken to CreateMember.
  • When the member is created, an internal link between the Loyalty member and the external issuer account is created.

Linking external issuers to new Loyalty accounts (paid)

To link a new Loyalty member on a paid membership tier to an external issuer account:

  • Generate a paid member using SetLoyaltyMembershipPackageActivation and CompleteOrder.
  • Follow above instructions to link an existing Loyalty member to an external issuer account.

Token validation and expiry

JWT tokens are returned with the expires_in property indicating how many seconds until the token expires. Alternatively, the Connect API will return the following responses if an invalid or expired token is provided.

HTTP Response code 401

{
    "ErrorCode": "InvalidLoyaltyToken",
    "Errors": [
        {
            "Description": "loyaltySessionToken is invalid"
        }
    ]
}

HTTP Response code 401

{
    "ErrorCode": "ExpiredLoyaltyToken",
    "Errors": [
        {
            "Description": "loyaltySessionToken is expired"
        }
    ]
}

The token can be refreshed via the refresh_token using the RefreshAuthentication endpoint.

POST: /loyalty/auth/refresh-authentication

Request:

{
  "refreshToken": "d1af6381fd6043e48a735e283fa8345b"
}

Response:

{
    "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjhEQzY4ODU2ODI1RU...",
    "token_type": "bearer",
    "expires_in": 899,
    "refresh_token": "1aa517ec7a824de09cbc3f363b402bb1"
}

Invalid authentication lockout

If a member makes multiple invalid attempts to authenticate, Loyalty may be configured to lock the member from further attempts. If a locked member tries to authenticate, Connect will return the following response.

HTTP Response Code 400

{
    "lockOutPeriodInSeconds": 900,
    "errorCode": "110",
    "errors": [
        {
            "description": "Member locked due to too many failed login attempts."
        }
    ]
}

lockoutPeriodInSeconds is the total amount of time the member will be locked starting from the time of the authentication request that caused the member to be locked. This value does not reflect the amount of time remaining before the member is no longer locked.

Authentication using ValidateMember (legacy)

In pre-5.0.3 versions, the only way to authenticate a member is by using the ValidateMember endpoint.

This endpoint will accept various combinations of credentials (depending on security configuration), perform the validation, and, optionally, return the member details.

POST: /restloyalty.svc/member/validate

Request:

{
    "UserSessionId": "{{userSessionId}}",
    "MemberLogin": "myusername",
    "MemberPassword": "mypassword",
    "ReturnMember": "true"
}

The userSessionId parameter links this authenticated member to the specified order also using the userSessionId.

Response:

{
    "ExtendedResultCode": 0,
    "IsWebAccountActivated": false,
    "Member": null,
    "LoyaltySessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "LoyaltyMember": {
        "MemberId": "1Y8BR0MVWGN",
        "FirstName": "Rick",
        "LastName": "Sanchez",
        "CardNumber": "700023432",
        "Email": "rick.sanchez@ricks.org",
        "ClubID": "1",
        "BalanceList": [
            {
                "BalanceTypeID": "2",
                "Name": "ABC Bonus Dollars",
                "PointsRemaining": 7,
                "RedemptionRate": 0
            }
        ],
        "UserName": "ricksanchez",
        "ClubName": "ABC Bonus club",
        "ContactByThirdParty": false,
        "MemberLevelId": 4,
        "MemberLevelName": "Gold",
        "LoyaltySessionExpiry": "/Date(1538334937713+1300)/",
    },
    "Result": 0
}

Using the ValidateMember endpoint links your Loyalty session to the userSessionId. This allows certain endpoints to accept a userSessionId instead of a loyaltySessionToken, however, we recommend to always supply the loyaltySessionToken.

Ending a Loyalty session

Loyalty sessions will be cleaned up by Connect as they expire. If you want to end one early, use the SignOutMember endpoint. This endpoint will sign the member out of Loyalty and can optionally cancel the order the member has been associated with via the CancelAssociatedOrder parameter.