DEV Community

Binary Storms
Binary Storms

Posted on

A ruby SDK for integrating with Civic SIP

What is Civic

Civic is the next generation blockchain based secure identity management platform. It allows to authenticate users without the need for traditional physical IDs, knowledge based authentication, username/password, and two-factor hardware tokens. Civic's Secure Identity Platform (SIP) uses a verified identity for multi-factor authentication on web and mobile apps without the need for usernames or passwords. The SIP provides partners with functionality such as:

  • secure public or private 2FA user login
  • onboarding of verified users with customized flows

Integrating with Civic

Currently only Civic Hosted option is available for partners integration. This is the simplest route to integration as it provides a flow similar to the traditional OAuth2 authorization code flow, with Civic performing the role of the Authorization server. This option delivers a secure solution and minimizes server side development required by the partner.

The following user signup example explains the general Civic Hosted option code flow:

Civic SIP flow

As illustrated above, the number of steps involved in the secure interactions with Civic SIP service can be daunting.

This is where a server-side ruby SDK comes in handy.

The open source Ruby SDK

I would like to introduce an open source Ruby SDK for interacting with Civic's SIP. This SDK abstracts away all the details of JWT encoding, decoding, verification and AES encryption/decryption.

If your ruby project leverages this SDK, the entire Civic SIP integration flow would look like:

  • Set up the frontend.
<link rel="stylesheet" href="https://hosted-sip.civic.com/css/civic-modal.min.css">
<script src="https://hosted-sip.civic.com/js/civic.sip.min.js"></script>
  • Initialize the frontend JS library.
var civicSip = new civic.sip({ appId: 'YOUR_CIVIC_APPLICATION_ID' });
  • Set up the sign-in button.
<button id="signupButton" class="civic-button-a medium" type="button">
    <span>Log in with Civic</span>
</button>
  • Set up event handling.
var button = document.querySelector('#signupButton');
    button.addEventListener('click', function () {
        civicSip.signup({ style: 'popup', scopeRequest: civicSip.ScopeRequests.BASIC_SIGNUP });
});

// Listen for data
civicSip.on('auth-code-received', function (event) {
    /*
        event: {
            event: "scoperequest:auth-code-received",
            response: "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJqdGkiOiI2Y2EwNTEzMi0wYTJmLTQwZjItYTg2Yi03NTkwYmRjYzBmZmUiLCJpYXQiOjE0OTQyMjUxMTkuMTk4LCJleHAiOjE0OTQyMjUyOTkuMTk4LCJpc3MiOiJjaXZpYy1zaXAtaG9zdGVkLXNlcnZpY2UiLCJhdWQiOiJodHRwczovL3BoNHg1ODA4MTUuZXhlY3V0ZS1hcGkudXMtZWFzdC0xLmFtYXpvbmF3cy5jb20vZGV2Iiwic3ViIjoiY2l2aWMtc2lwLWhvc3RlZC1zZXJ2aWNlIiwiZGF0YSI6eyJjb2RlVG9rZW4iOiJjY2E3NTE1Ni0wNTY2LTRhNjUtYWZkMi1iOTQzNjc1NDY5NGIifX0.gUGzPPI2Av43t1kVg35diCm4VF9RUCF5d4hfQhcSLFvKC69RamVDYHxPvofyyoTlwZZaX5QI7ATiEMcJOjXRYQ",
            type: "code"
        }
    */

    // encoded JWT Token is sent to the server
    var jwtToken = event.response;

    // Your function to pass JWT token to your server
    sendAuthCode(jwtToken);
  });

  civicSip.on('user-cancelled', function (event) {
    /*
        event:
        {
          event: "scoperequest:user-cancelled"
        }
    */
   });

  civicSip.on('read', function (event) {
    /*
        event:
        {
          event: "scoperequest:read"
        }
    */
  });

   // Error events.
   civicSip.on('civic-sip-error', function (error) {
      // handle error display if necessary.
      console.log('   Error type = ' + error.type);
      console.log('   Error message = ' + error.message);
   });
  • Complete the process on the server side. The JWT token obtained on the frontend is temporary, akin to an OAuth authorization grant. This JWT token needs to be exchanged via the server side SDK in order to complete the process and receive user data.
require 'civic_sip_sdk'

# appId - your Civic application id
# env - your Civic app environment, :dev or :prod (default)
# private key - your Civic private signing key
# secret - your Civic secret
client = CivicSIPSdk.new_client('appId', :env, 'private key', 'secret')
user_data = client.exchange_code(jwt_token: 'your token from Civic frontend JS lib')
  • Access user data. The user data can be accessed in 2 ways; either by iterating over the list of all the user data items or by accessing a particular user data item by label name.
    • by iterating all items
# Civic userId value
user_id = user_data.user_id
# get a list of all the user data items
data_items = user_data.data_items
# you can access all the attributes in each data item
an_item = data_items.first
label = an_item.label
value = an_item.value
is_valid = an_item.is_valid
is_owner = an_item.is_owner
* by label name
an_item = user_data.by_label('contact.personal.email')
label = an_item.label
value = an_item.value
is_valid = an_item.is_valid
is_owner = an_item.is_owner

Next Step

If you are developing a product in ruby, Civic SIP can be a great way to provide secure identity services to your users. The ruby SDK will simplify the integration process.

Top comments (0)