Classy Login (Pre-release)

Classy's Single Sign On service is a convenient way for people to register and log into your app using their Classy account. Classy's Single Sign On implementation complies with OpenID Connect.

This document describes Classy's implementation of OpenID Connect and the tools made available to 3rd party developers to help them use Classy as an OpenID Identity Provider.

Note for "power developers"

If you are already familiar with OpenID Connect protocol, here is all you need to know to configure Classy as an Identity Provider:

Endpoint URL
Authorization endpoint
https://login.classy.org/authorize
Token endpoint
https://api.classy.org/oauth2/auth
User info endpoint
https://api.classy.org/2.0/me

Single Sign On flow - Overview

Classy single sign on flow

During this flow:

  1. The user that needs to be authenticated is sent to https://login.classy.org/authorize?client_id={your_app_ID} (aka the "Authorization endpoint"),
  2. The user authenticates, an authorization code is generated and passed to your application,
  3. Your application exchanges the authorization code with an access token that can be used to retrieve the user identity.

There are several ways to send the user to the authorization endpoint and to retrieve the authorization code:

  1. The "redirect method" during which the user is redirected to the authorization endpoint and redirected back to your application,
  2. The "popup" and the "iframe" methods during which the user never leaves your application. These methods require the use of our javascript SDK.

The way the authorization code is passed back to your app depends on the method ("redirect", "popup" or "iframe") being used.

Implementing the flow, step by step

Step One - Send the user to the Authorization endpoint

Using the redirect method

When your application needs to authenticate a user, this user shall be redirected to the authorization endpoint. The authorization endpoint URL is of the form:

        https://login.classy.org/authorize
                    ?client_id=xxx
                    &response_type=code
                    &state=xxx
                    &redirect_uri=xxx
                    &scope=xxx
    

Where:

Parameter Requirement Description
client_id Required The client_id you got when registering your application.
response_type Required The only OpenID Connect supported response_type by Classy is "code"
redirect_uri Required URI the user will be redirected to once he authorized your application. It must be equal to one of the redirect_uri you defined when you registered your application.
scope Required Comma separated list of scope your app is requesting. The "Scope" section of this document details what the available scope are.
state Optional A string to let your app maintain state between the request and callback. When the user is redirected to your application, the state parameter will be included. You should use this parameter to prevent cross-site request forgery.

Using the popup method

You first need to include the javascript SDK in your page.

Then, just bind the classy-login-btn class to an html element. The single-sign-on popup will be thrown when the user clicks this element. You must also define the function that will handle the authorization code once the user has authorized your application ("authHandler" in our example).

Where:

Parameter Requirement Description
data-callback Required The name of the javascript function that will be called to handle the authorization code.
data-scope Required Comma separated list of scope your app is requesting. The "Scope" section of this document details what the available scope are.
data-flow Optional

When the user is sent to the authorize endpoint he must be authenticated on login.classy.org. If this is not the case, the user is redirected to the login form. You can customize this default behavior with this parameter.

data-flow can take 3 values:

  • login (default) - the user is redirected to the login page. He can chose to signup if he does not have a Classy account already.
  • signup - the user is redirected to the signup page. He can chose to login if he already has a Classy account.
  • login_only - the user is redirected to the login page. He cannot signup.

Alternatively, you can also use the Classy.login() method provided by the SDK:

Classy.ready(function() { // This will launch the single sign on popup as soon as the SDK is loaded and initialized options = { "scope": "read_profile", "flow": "login" }; Classy.login(options, authHandler); }); function authHandler(response) { // see step 2 }

Using the iframe method

You first need to include the javascript SDK in your page.

Include a container for the iframe in your page with the classy-login-iframe class.

Where:

Parameter Requirement Description
data-callback Required The name of the javascript function that will be called to handle the authorization code.
data-scope Required Comma separated list of scope your app is requesting. The "Scope" section of this document details what the available scope are.
data-flow Optional

When the user is sent to the authorize endpoint he must be authenticated on login.classy.org. If this is not the case, the user is redirected to the login form. You can customize this default behavior with this parameter.

data-flow can take 3 values:

  • login (default) - the user is redirected to the login page. He can chose to signup if he does not have a Classy account already.
  • signup - the user is redirected to the signup page. He can chose to login if he already has a Classy account.
  • login_only - the user is redirected to the login page. He cannot signup.

Step 2 - Retrieve the authorization code

Once the user authorized your app on login.classy.org, an authorization code is generated. The way the authorization code is communicated to your application depends on the SSO method chosen.

Using the redirect method

Once the user authorized your app, he will be redirected to:

<redirect_uri>?code=xxx&state=xxx

Where:

Parameter Description
redirect_uri redirect_uri used to build the authorization endpoint (step 1).
code The authorization code.
state state parameter used to build the authorization endpoint at step 1. Your app must confirm that this parameter received from Classy matches the one created at step 1.

Using the popup or iframe methods

The authorization code will be passed to the callback method bound to the html element ("authHandler" in our example). This method shall pass this authorization code to your backend server.

function authHandler(response) { if (response.authorization_code) { // pass the authorization code to your backend. Can be down with a redirection or an ajax call for instance. window.location.href = "/oauth2_callback?code=" + response.authorization_code; } else { // handle error. console.log("SSO failed: " + response.error); } }

Step 3 - Exchange the authorization code with a member access token

Once your backend is in possession of the authorization code, it can be exchanged with an access token:

POST /oauth2/auth HTTP/1.1 Host: api.classy.org Content-Type: application/x-www-form-urlencoded code={authorization_code}&client_id={your_client_id}&client_secret={your_client_secret}&grant_type=authorization_code

An access token will be returned:

{ "access_token": "f22d113d5bad4472c4bcb208f39c959b", "refresh_token": "3b9b4cb5b3a84708c74fa5fd2e40ce97", "expires_in": 3600, "token_type": "bearer" }

Step 4 - Retrieve the user identity

You can now retrieve the user identity by requesting the GET /2.0/me endpoint using the access token.

GET /2.0/me HTTP/1.1 Host: api.classy.org Authorization: Bearer f22d113d5bad4472c4bcb208f39c959b

which will return a response containing the following data:

{ "id": "{Classy member ID}", "first_name": "...", "last_name": "...", "email_address": "..." }

Javascript SDK

Classy is providing a javascript SDK to help you implement the "popup" and the "iframe" methods of the SSO flow.

Installing the SDK

Just include the following lines in your pages, just before the </body> tag of your html document:

SDK Reference

The SDK is asynchronously loaded so that it doesn't block loading other elements of your page. As a result, you must wait for the SDK to be loaded and initialized before using any of its methods:

Classy.login(options, callback)

This method will launch a popup asking a user to authenticate on Classy and authorize (if not already done) your app for the requested scope. The callback function is called with the authorization result.

Classy.status(callback)

This method will provide information regarding the login status of the user on login.classy.org.

Classy.logout(callback)

This method logs the user out of login.classy.org.

Classy.parseDOM()

If HTML elements having the classy-login-btn or the classy-login-iframe class were added to the document after the SDK was initialized, they won't be taken into account by the SDK.

This method will let the SDK re-parse the document.

Authorization Scope

When sending the user to the authorization endpoint, you must define the "scope" of the authorization your app is requesting. A scope is a set of permissions your app is asking a user to grant. It will affect the consent screen the user will see on login.classy.org.

Here is the list of the scope currently made available:

Name Description
profile deprecated
  • Grant access to basic user information (Classy ID, first and last name, email address, profile picture, etc.)
read_profile
  • View member profile information (Classy ID, first and last name, email address, profile picture, etc.)
write_profile
  • Update member profile information (first and last name, profile picture, change password, etc.)
read_fundraising_pages
  • View information for fundraising pages you own or manage
write_fundraising_pages
  • Update information for fundraising pages you own or manage
  • Create fundraising pages on your behalf
  • Delete fundraising pages you own or manage
read_fundraising_teams
  • View information for fundraising teams you own/captain/manage
write_fundraising_teams
  • Update information for fundraising teams you own/captain/manage
  • Delete fundraising teams you own/captain/manage
  • Create fundraising teams on your behalf
read_campaigns
  • View information for campaigns you manage
write_campaigns
  • Update information for campaigns you manage
  • Publish/unpublish campaigns you manage
  • Create campaigns on your behalf
read_organizations
  • View information for organizations you manage
write_organizations
  • Update information for organizations you manage
read_supporters
  • View information for supporters (aka contacts) you manage
write_supporters
  • Update information for supporters (aka contacts) you manage
  • Create contacts for your organizations
read_transaction_history
  • View information for transactions to organizations, campaigns, etc. that you manage
read_transaction_reports
  • View aggregate reports for your organizations, campaigns, etc.
write_transactions
  • Update information for transactions you manage
  • Create offline transactions
write_email
  • Send email on your behalf
read_feeds
  • View activity feeds, comments, "My Story" feeds, etc.
write_feeds
  • Create activity, comments, "My Story" entries, etc.