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.
If you want to use third-party Cordova plugins, you need to create a custom build debugger (Android or iOS).
Tested Environment
- Android 11.0
- iOS 14.3

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.
- 2.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) - 3.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.)
- 4.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. - 5.Select the
Settings
tab and fromApp permissions
, grantRead and Write
permissions. If you do not tweet from the app, only allowRead
permission. - 6.Select the
Settings
tab and fromAuthentication
, enable3-legged OAuth
.
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.
- 1.From the Monaca Cloud IDE, select
Settings → Manage Cordova Plugins
. - 2.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.- 1.From Monaca Cloud IDE, select
Settings → Add / Remove JS / CSS Components
. - 2.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.

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 |
<!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- 1.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.
- 2.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.
- 3.Tweet block:There is a text area and a button to tweet.
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.If you check "Remember me" on the Twitter login screen, the authorization screen will be displayed in the logged-in state without entering the account and password from the next time. If you want to log out from Twitter, please sign out from the icon on the upper right of the authorization screen.
In this app, the login information (access token) is temporarily stored in the variable model, so the login information will be lost when the app is restarted. If you want to stay logged in, save your access token and user ID in a persistent location such as localstorage.
Last modified 1yr ago