Twitter Single Sign-on App
Here, we will explain the method of single sign-on (SSO) using OAuth on Twitter.
For single sign-on, use the InAppBrowser plug-in and a third-party advanced-http plug-in, and the signature required for OAuth uses the oauth-signature library.
After successful authentication, you can display the user's basic information on the app and post tweets.
Demo
Import Twitter Single Sign-on App to your Monaca Account
Tested Environment
Android 11.0
iOS 14.3

Prerequisite
Getting Twitter Consumer Key and Consumer Secret
To use the Twitter API, you need to register a developer account. Register a developer account from Twitter Developer Account.
Next, on the Twitter Developer Portal page, register your app and issue a Consumer Key (API key), Consumer Secret (API secret key), and Bearer token.
Create Standalone Apps from the
Create App
button at the bottom of the screen. (Instead of creating Standalone Apps, you can create Apps under Projects)Enter the Name (app name), Description (app description), and Website (URL from which the app will be downloaded). (* You cannot use a name that has already been used. There is a limit to the number of apps that can be created per day.)
Enter the Callback URL (optional: the page that will be displayed after successful authentication). In this sample app, set
mymonacaapp://
. Please change to the one for your app later. This Callback URL is also required when implementing the app.Select the
Settings
tab and fromApp permissions
, grantRead and Write
permissions. If you do not tweet from the app, only allowRead
permission.Select the
Settings
tab and fromAuthentication
, enable3-legged OAuth
.
Import plugin
We will use the InAppBrowser plugin and a third-party advanced-http plugin for single sign-on and use the oauth-signature library to create the signatures needed for OAuth.
From the Monaca Cloud IDE, select
Settings → Manage Cordova Plugins
.Enable the
InAppBrowser
plugin.

3. Click the button "Import Cordova Plugin", check "Specify URL or package name", enter cordova-plugin-advanced-http
for the package name, and click the OK button.
Import JS components
From Monaca Cloud IDE, select
Settings → Add / Remove JS / CSS Components
.Search by typing
oauth-signature-js
in the component search form. Installoauth-signature-js
from the search results. After that, selectcomponents/oauth-signature-js/dist/oauth-signature.js
in the selection of the load target and save it. Please note that theoauth-signature.js
library is BSD-3-Clause, so please be careful when distributing the source code and binary code of the application.
App description
File organization

File
Description
index.html
App screen page
css/style.css
App stylesheet
js/app.js
JavaScript file that performs various processing when the application is executed
HTML description
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta http-equiv="Content-Security-Policy" content="default-src * data: gap: content: https://ssl.gstatic.com; style-src * 'unsafe-inline'; script-src * 'unsafe-inline' 'unsafe-eval'">
<script src="components/loader.js"></script>
<link rel="stylesheet" href="components/loader.css">
<link rel="stylesheet" href="css/style.css">
<script src="js/app.js"></script>
</head>
<body>
<h2>Twitter Sample</h2>
<div>
<button onclick="connect()">Connect !</button>
<p>Your Id:
<span id="tw-id"></span>
</p>
<p>Your Name:
<span id="tw-name"></span>
</p>
<hr>
<button id="showMe" onclick="showMe()">Show Me</button>
<p>Your Info:
<span id="tw-profile"></span>
</p>
<img id="tw-profile-image" class="profile">
<hr>
<p>
<textarea id="tweetText" rows=5 cols=40>Hello</textarea>
</p>
<button id="tweetBtn" onclick="sendTweet()">Send Tweet</button>
</div>
</body>
</html>
This page is the application screen.
This page is roughly divided into 3 blocks. Each block is separated by <hr>
tags
Login block:
There is a button to move to the Twitter login screen and a component that displays the user ID and user name (screen name) after login.
Profile block:
There is a button to get the profile of the logged-in user and a component to display it after a successful acquisition.
Tweet block:
There is a text area and a button to tweet.
JavaScript description
app.js
const apiKey = '[Consumer Key(API key)]';
const secretKey = '[Consumer Secret (API key secret)]';
const callbackURL = '[Registered callback URL (scheme)]';
const signatureMethod = "HMAC-SHA1";
const version = "1.0";
const requestTokenURL = "https://api.twitter.com/oauth/request_token";
const loginURL = "https://api.twitter.com/oauth/authorize"
const accessTokenURL = "https://api.twitter.com/oauth/access_token";
const updateURL = "https://api.twitter.com/1.1/statuses/update.json";
const usersShowURL = "https://api.twitter.com/1.1/users/show.json";
let model = {};
function percentEncode(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, char => '%' + char.charCodeAt().toString(16));
}
function getNonce() {
const array = new Uint8Array(32);
window.crypto.getRandomValues(array);
return Array.from(array).map(uint => uint.toString(16).padStart(2, '0')).join('');
}
function oauthSend(url, method, accessTokenSecret, data, oauth_params, cb) {
const timestamp = (Math.floor(Date.now() / 1000)).toString(10);
const parameters = Object.assign(
{},
oauth_params,
{
oauth_nonce: getNonce(),
oauth_signature_method: signatureMethod,
oauth_timestamp: timestamp,
oauth_version: version
},
data
);
const signature = oauthSignature.generate(method.toUpperCase(),
url,
parameters,
secretKey,
accessTokenSecret
);
const authorizationHeader = "OAuth " + Object.keys(parameters).map((key) => {
return percentEncode(key) + '="' + percentEncode(parameters[key]) + '", '
}).join('') + 'oauth_signature=\"' + signature + '\"';
const urlWithParams = method.toUpperCase() === "GET" ?
url + "?" + Object.keys(data).map(function(k) {
return encodeURIComponent(k) + '=' + encodeURIComponent(data[k])
}).join('&') : url;
cordova.plugin.http.sendRequest(urlWithParams, {
method: method,
headers: {'Authorization': authorizationHeader},
data: data,
serializer: null
}, (res) => {
cb(res);
}, (error) => {
alert(error.error);
});
}
function connect() {
oauthSend(requestTokenURL, 'post', "", {}, {
oauth_callback: callbackURL,
oauth_consumer_key: apiKey,
}, function (res) {
openLoginDialog(res.data);
});
}
function openLoginDialog(res) {
const oauth = res.split('&')[0];
const url = loginURL + "?" + oauth;
const ref = cordova.InAppBrowser.open(url, "_blank", 'location=yes,beforeload=get');
ref.addEventListener('beforeload', beforeLoad(ref));
}
function beforeLoad(ref) {
return function (event, cb) {
if (event.url && event.url.startsWith(callbackURL) ) {
const url = new URL(event.url);
const params = Array.from(url.searchParams.entries()).reduce(
function (acc, cur) {
acc[cur[0]] = cur[1];
return acc;
} , {}
);
ref.close();
getAccessToken(params);
} else {
cb(event.url);
}
};
}
function getAccessToken(params) {
oauthSend(accessTokenURL, 'post', "", {}, {
oauth_verifier: params.oauth_verifier,
oauth_token: params.oauth_token,
oauth_consumer_key: apiKey,
}, function (res) {
const params = Array.from(new URLSearchParams(res.data).entries()).reduce(
function (acc, cur) {
acc[cur[0]] = cur[1];
return acc;
} , {}
);
document.getElementById('tw-id').innerHTML = params.user_id;
document.getElementById('tw-name').innerHTML = params.screen_name;
model.oauth_token = params.oauth_token;
model.oauth_token_secret = params.oauth_token_secret;
model.user_id = params.user_id;
});
}
function sendTweet() {
const text = document.querySelector("#tweetText").value;
oauthSend(updateURL, 'post', model.oauth_token_secret, { "status": text }, {
oauth_token: model.oauth_token,
oauth_consumer_key: apiKey
}, function (res) {
alert("Tweet しました");
});
}
function showMe() {
oauthSend(usersShowURL, 'get', model.oauth_token_secret, { "user_id": model.user_id }, {
oauth_token: model.oauth_token,
oauth_consumer_key: apiKey
}, function (res) {
const profile = JSON.parse(res.data);
document.querySelector("#tw-profile").innerHTML =
"name: " + profile["name"] + "<br>" +
"screen_name: " + profile["screen_name"] + "<br>" +
"location: " + profile["location"] + "<br>" +
"description: " + profile["description"] + "<br>";
document.querySelector("#tw-profile-image").src = profile["profile_image_url_https"].replace("_normal", "");
});
}
In the first three lines of the file, set the API key (consumer key), API key secret (consumer secret), and callback URL you obtained from the Twitter Developer account.
const apiKey = '[Consumer Key(API key)]';
const secretKey = '[Consumer Secret (API key secret)]';
const callbackURL = '[Registered callback URL (scheme)]';
Tap the Connect button to display the authentication screen.
After a successful login, the access token and user ID are stored in the variable model
. In this sample app, there is no log-out function, so you need to kill the app from the task to cancel the login status.
Then tap the Show Me
button to see the logged-in user information and the icon. Furthermore, when you tap the Send Tweet
button, the message entered in the text form will be posted to Twitter.
Last updated
Was this helpful?