TypeScript SDK v2.0 Major Release

This document documents the major changes introduced in v2.0.0 sgID TypeScript SDK, and serves as a step-by-step guide for existing v1.x.x sgID TypeScript SDK users to upgrade their version to v2.x.x.

Key Release Notes

  1. PKCE is introduced, and its implementation is mandated. According to OAuth 2.0 Security Best Current Practice:

    For confidential clients, the use of PKCE [RFC7636] is RECOMMENDED, as it provides a strong protection against misuse and injection of authorisation codes as described in Section 4.5.3.1 and, as a side-effect, prevents CSRF even in presence of strong attackers as described in Section 4.7.1.

  2. SgidClient.authorizationUrl(), SgidClient.callback(), and SgidClient.userinfo() now take in a single options object as a parameter, instead of sequential, possibly optional parameters. Refer to SgidClient’s module file SgidClient.d.ts for implementatino details.

  3. sub is now required in userinfo() calls, which can be retrieved from the response returned from callback() .

  4. In light of all the breaking changes above, users are strongly recommended to refer to the example upgrade path outlined below to safely migrate their applications to v2.x SDK. Deprecation of the v1.x SDK will take place in 31st December 2023, therefore any existing users who has yet to upgrade their SDK version by then will face disruptions in their application(s).

  5. The Developer Documentation has been revamped, containing the newest changes. Users can refer to the documentation for a better understanding of how sgID works.

Upgrade Path

The code below assumes the following contexts for Client Application:

  • Client Application is a full stack web application.

  • Client Application consists of a SPA and an Express back-end server.

  • Client Application manages state in its back-end server's session.

Refer to the Framework Guides Section for how a Next.js implementation might look like.

Installing the Latest Release

Run npm i @opengovsg/sgid-client@2.0.0 (or any newer minor/patch versions released in the future) for all directories that

  • contain a package.json file, and

  • have a dependency to @opengovsg/sgid-client in the corresponding package.json file.

Authorization Request (authorizationUrl(…))

For every OAuth request, generate a PKCE pair (consisting of code challenge and code verifier). Do not reuse the same PKCE pairs for any requests.

Call authorizationUrl() with the correct options object.

Before (DO NOT COPY):

// Generate an authorization URL
  const { url, nonce } = sgid.authorizationUrl(
    state,
    ['openid', 'myinfo.name']
    )

After:

// Generate a PKCE pair
  const { codeChallenge, codeVerifier } = generatePkcePair()
  
// Generate an authorization URL
  const { url, nonce } = sgid.authorizationUrl({
    state,
    codeChallenge,
    scope: ['openid', 'myinfo.name']
    })

Store the Verifier with the corresponding session ID, alongside its state and nonce if applicable:

// Store session data
sessionData[sessionId] = {
    state,
    nonce,
    codeVerifier
}

Access Token Request (callback(…))

Retrieve the code verifier from the session and pass it in callback()as part of the options object.

Before (DO NOT COPY):

// Exchange the authorization code and code verifier for the access token
const { accessToken, sub } = await sgid.callback(code, session.nonce)

After:

// Exchange the authorization code and code verifier for the access token
const { accessToken, sub } = await sgid.callback({
  code,
  nonce: session.nonce,
  codeVerifier: session.codeVerifier,
})

Retrieving User info (userinfo(…))

Note the inclusion of sub as one of the fields in the options object.

Before (DO NOT COPY):

//Request user info using the access token
const userinfo = await sgid.userinfo(accessToken)

After:

//Request user info using the access token
const userinfo = await sgid.userinfo({
  accessToken,
  sub
})

Congratulations!

You should have the v2 SDK successfully integrated into your application!

FAQ

Q: What if my application does not follow the same architecture as the example Application described?

A: Unfortunately it is infeasible to list out all possible upgrade paths as there are too many possible architectures for an application in practice. However, the example upgrade path should serve as an adequate reference guide for the necessary changes to migrate to v2 SDK.

Q: I'm stuck at Step X and I don't know what to do. How can I proceed?

A: Feel free to drop us a message at this form for further clarification.

Last updated