1.0.0 • Published 2 years ago

@uraikus/sso v1.0.0

Weekly downloads
-
License
ISC
Repository
-
Last release
2 years ago

uraik.us SSO

uraik.us anonymous Single Sign-On (SSO) is a secure, fast, and simple login tool that doesn't track its users. With bot-stopping mechanisms and pre-generated passcodes, its never been easier to make an account or to implement SSO.

Client implementation is extremely easy (no dependency required):

var sso = {origin: 'https://sso.uraik.us'}
addEventListener('message', ev => {
  if (ev.origin === sso.origin) {
    if (ev.data === 'ready') sso.window.postMessage('credentials', sso.origin)
    else if (ev.data && ev.data.type === 'credentials') {
      sso.credentials = ev.data // {publicKey: 'abcdf...', userId: 3, type: 'credentials'}
      shareWithServer(ev.data)
    }
  }
})
sso.window = open(sso.origin, 'sso')

To prevent user spoofing, you can validate the key with the server:

Client:

function shareWithServer(theCreds) {
  fetch('/validate-sso', {
    method: 'POST',
    headers: {
      'content-type': 'application/json'
    },
    body: JSON.stringify(theCreds)
  })
}

To validate the credential on your server, make an http request with the public key to the address below:

POST https://sso.uraik.us/apiv1/validate BODY: {publicKey: 'abbDKsdlfk...'}
RESPONSE: {userId: 3}

Example (ExpressJS):

router.post('/validate-sso', (req, res, next) => {
  let fetch = require('node-fetch')
  fetch('https://sso.uraik.us/apiv1/validate', {
    method: 'POST',
    headers: {
      'content-type': 'application/json'
    },
    body: JSON.stringify(req.body)
  })
    .then(r => {
      if (r.ok) {
        res.cookie('public_key', body.publicKey, { expires: new Date(Date.now() + 900000), httpOnly: true })
        res.send()
      } else res.status(401).send('Unauthorized')
    })
})

You can also use the SSO middleware for the ExpressJS validation:

app.use(require('@uraikus/sso'))
app.use((req, res) => {
  req.userId // will be null if validation failed
})

This middleware will validate the authorization http header and put the userId into the request object. So when sending requests from the client after logging in, include the publicKey in the authorization header.

Client:

fetch(url, {
  headers: {
    authorization: 'Bearer ' + sso.publicKey
  }
})