Failed to get tokens using Azure AD and SPA - javascript

I am developing my web app, it is a single page application. I want to integrate it with Azure Aactive Directory to login users and call microsoft graph API .
I am following this doc:https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-protocols-oidc .
But seems it is not so smoothly when I tried to get an ID token or access token, I always got an error:
blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource . How could I solve it ?Am I in the right direction? Thanks!

As superstar #GauravMantri mentioned, if you are developing a SPA, you should use MSAL.js to log in users and get tokens. Call REST API directly not works here.
Just try the .html code below to log in users and get an access token to Microsoft Graph API:
<html>
<head>
<meta charset="utf-8">
<title>Azure AD test</title>
<script type="text/javascript" src="https://alcdn.msauth.net/lib/1.4.4/js/msal.min.js"></script>
</head>
<body>
<div >
<button id="SignIn" onclick="signIn()">Sign in</button><br/>
<div id="WelcomeMessage"/><br/>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
var clientAppID = "<your public client Azure AD APP ID>"
var tenantID = "<your tenant ID>"
var demoScops = {
scopes:["https://graph.microsoft.com/User.Read"]
}
var msalConfig = {
auth: {
clientId: clientAppID,
authority: "https://login.microsoftonline.com/" + tenantID
},
cache: {
cacheLocation: "localStorage",
storeAuthStateInCookie: true
}
};
var myMSALObj = new Msal.UserAgentApplication(msalConfig);
myMSALObj.handleRedirectCallback(authRedirectCallBack);
function signIn() {
myMSALObj.loginPopup(demoScops).then(function (loginResponse) {
console.log(loginResponse);
initPage();
}).catch(function (error) {
console.log(error);
});
}
function initPage(){
showWelcomeMessage();
callGraphApi();
}
function showWelcomeMessage() {
var divWelcome = document.getElementById('WelcomeMessage');
divWelcome.innerHTML = 'welcome! ' + myMSALObj.account.userName + '</br>';
var loginbutton = document.getElementById('SignIn');
loginbutton.innerHTML = 'sign out';
loginbutton.setAttribute('onclick', 'signOut();');
}
function callGraphApi(){
myMSALObj.acquireTokenSilent(demoScops).then(function (tokenResponse) {
var accessToken = tokenResponse.accessToken;
$.ajax({
url: "https://graph.microsoft.com/v1.0/me",
type: "GET",
async: false,
beforeSend: function(xhr){xhr.setRequestHeader('Authorization', 'Bearer '+ accessToken);},
success: function(data) {
console.log(data)
}
});
}).catch(function (error) {
console.log(error);
})
}
function authRedirectCallBack(error, response) {
if (error) {
console.log(error);
}
}
function requiresInteraction(errorCode) {
if (!errorCode || !errorCode.length) {
return false;
}
return errorCode === "consent_required" ||
errorCode === "interaction_required" ||
errorCode === "login_required";
}
var ua = window.navigator.userAgent;
var msie = ua.indexOf('MSIE ');
var msie11 = ua.indexOf('Trident/');
var msedge = ua.indexOf('Edge/');
var isIE = msie > 0 || msie11 > 0;
var isEdge = msedge > 0;
var loginType = isIE ? "REDIRECT" : "POPUP";
if (loginType === 'POPUP') {
if (myMSALObj.getAccount()) {
initPage()
}
}
else if (loginType === 'REDIRECT') {
document.getElementById("SignIn").onclick = function () {
myMSALObj.loginRedirect(requestObj);
};
if (myMSALObj.getAccount() && !myMSALObj.isCallback(window.location.hash)) {
initPage()
}
} else {
console.error('Please set a valid login type');
}
function signOut() {
window.localStorage.clear();
myMSALObj.logout();
}
</script>
</html>
Let me know if you have any more questions.

Related

My API work in postman but it's not working in my cofe visual studio and chrome

When I try my code in postman it's work very well but in my code in visual studio I got a CORS error,
this is my API, using Google Apps Script:
function doPost(e) {
var params = JSON.parse(e.postData.contents);
var action = params.action;
if (action == 'login') {
return handleLogin(params);
} else if (action == 'signup') {
return handleSignup(params);
} else {
return ContentService.createTextOutput("Invalid action");
}
}
function handleLogin(params) {
var username = params.username;
var password = params.password;
var data = sheet.getDataRange().getValues();
for (var i = 0; i < data.length; i++) {
if (data[i][0] == username && data[i][1] == password) {
return ContentService.createTextOutput("Login successful!");
}
}
return ContentService.createTextOutput("Invalid username or password");
}
And here my javascript code, I use the same endpoint, and JSON.stringfy(data),
I do not konw where is the problem,
I install the CORS extension, but the same problem
const data = {action : 'login', username, password};
btn_login.addEventListener('click', getUser);
async function getUser(){
const res = await fetch(api, {
method : 'POST',
mode : 'cors',
cache : 'default',
credentials : 'same-origin',
redirect : 'follow',
referrerPolicy : 'no-referrer',
headers : {
'Content-Type' : 'text/plain'
},
body : JSON.stringify(data)
});
if(res.ok){
console.log(data);
window.location.replace('welcome.html');
}

Cannot authenticate to Web Playback API with authorization code flow

I would like to use the authorization code flow to authenticate with the Web Playback API. Unfortunately the playback does not work properly. My browser plays a couple of seconds and then skips all the tracks.
Using the temporary code from the docs works fine though.
I obtain the access_token via a server which connects to the Web API and redirect the callback to my client which should connect to the Web Playback API.
I found this question: problem playing songs via the spotify web api and javascript and the answerer suggested that an authorization code should work.
This is the server code to connect with the Web API:
index.html
<!doctype html>
<html>
<head>
<title>Example of the Authorization Code flow with Spotify</title>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<style type="text/css">
#login, #loggedin {
display: none;
}
.text-overflow {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 500px;
}
</style>
</head>
<body>
<div class="container">
<div id="login">
<h1>This is an example of the Authorization Code flow</h1>
Log in with Spotify
</div>
<div id="loggedin">
<div id="user-profile">
</div>
<div id="oauth">
</div>
<button class="btn btn-default" id="obtain-new-token">Obtain new token using the refresh token</button>
</div>
</div>
<script id="user-profile-template" type="text/x-handlebars-template">
<h1>Logged in as {{display_name}}</h1>
<div class="media">
<div class="pull-left">
<img class="media-object" width="150" src="{{images.0.url}}" />
</div>
<div class="media-body">
<dl class="dl-horizontal">
<dt>Display name</dt><dd class="clearfix">{{display_name}}</dd>
<dt>Id</dt><dd>{{id}}</dd>
<dt>Email</dt><dd>{{email}}</dd>
<dt>Spotify URI</dt><dd>{{external_urls.spotify}}</dd>
<dt>Link</dt><dd>{{href}}</dd>
<dt>Profile Image</dt><dd class="clearfix">{{images.0.url}}</dd>
<dt>Country</dt><dd>{{country}}</dd>
</dl>
</div>
</div>
</script>
<script id="oauth-template" type="text/x-handlebars-template">
<h2>oAuth info</h2>
<dl class="dl-horizontal">
<dt>Access token</dt><dd class="text-overflow">{{access_token}}</dd>
<dt>Refresh token</dt><dd class="text-overflow">{{refresh_token}}</dd>
</dl>
</script>
<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0-alpha.1/handlebars.min.js"></script>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
(function() {
/**
* Obtains parameters from the hash of the URL
* #return Object
*/
function getHashParams() {
var hashParams = {};
var e, r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
while ( e = r.exec(q)) {
hashParams[e[1]] = decodeURIComponent(e[2]);
}
return hashParams;
}
var userProfileSource = document.getElementById('user-profile-template').innerHTML,
userProfileTemplate = Handlebars.compile(userProfileSource),
userProfilePlaceholder = document.getElementById('user-profile');
var oauthSource = document.getElementById('oauth-template').innerHTML,
oauthTemplate = Handlebars.compile(oauthSource),
oauthPlaceholder = document.getElementById('oauth');
var params = getHashParams();
var access_token = params.access_token,
refresh_token = params.refresh_token,
error = params.error;
if (error) {
alert('There was an error during the authentication');
} else {
if (access_token) {
// render oauth info
oauthPlaceholder.innerHTML = oauthTemplate({
access_token: access_token,
refresh_token: refresh_token
});
$.ajax({
url: 'https://api.spotify.com/v1/me',
headers: {
'Authorization': 'Bearer ' + access_token
},
success: function(response) {
userProfilePlaceholder.innerHTML = userProfileTemplate(response);
$('#login').hide();
$('#loggedin').show();
}
});
} else {
// render initial screen
$('#login').show();
$('#loggedin').hide();
}
document.getElementById('obtain-new-token').addEventListener('click', function() {
$.ajax({
url: '/refresh_token',
data: {
'refresh_token': refresh_token
}
}).done(function(data) {
access_token = data.access_token;
oauthPlaceholder.innerHTML = oauthTemplate({
access_token: access_token,
refresh_token: refresh_token
});
});
}, false);
}
})();
</script>
</body>
</html>
app.js (via Node.js)
var express = require('express'); // Express web server framework
var request = require('request'); // "Request" library
var cors = require('cors');
var querystring = require('querystring');
var cookieParser = require('cookie-parser');
var client_id = 'MY_ID'; // Your client id
var client_secret = 'MY_SECRET'; // Your secret
var redirect_uri = 'http://localhost:8888/callback'; // Your redirect uri
/**
* Generates a random string containing numbers and letters
* #param {number} length The length of the string
* #return {string} The generated string
*/
var generateRandomString = function(length) {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
var stateKey = 'spotify_auth_state';
var app = express();
app.use(express.static(__dirname + '/public'))
.use(cors())
.use(cookieParser());
app.get('/login', function(req, res) {
var state = generateRandomString(16);
res.cookie(stateKey, state);
// your application requests authorization
var scope = 'streaming user-read-private user-read-email user-read-playback-state user-modify-playback-state';
res.redirect('https://accounts.spotify.com/authorize?' +
querystring.stringify({
response_type: 'code',
client_id: client_id,
scope: scope,
redirect_uri: redirect_uri,
state: state
}));
});
app.get('/callback', function(req, res) {
// your application requests refresh and access tokens
// after checking the state parameter
var code = req.query.code || null;
var state = req.query.state || null;
var storedState = req.cookies ? req.cookies[stateKey] : null;
if (state === null || state !== storedState) {
res.redirect('http://localhost:3000/#' +
querystring.stringify({
error: 'state_mismatch'
}));
} else {
res.clearCookie(stateKey);
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: redirect_uri,
grant_type: 'authorization_code'
},
headers: {
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token,
refresh_token = body.refresh_token;
var options = {
url: 'https://api.spotify.com/v1/me',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
// use the access token to access the Spotify Web API
request.get(options, function(error, response, body) {
console.log(body);
});
// we can also pass the token to the browser to make requests from there
res.redirect('http://localhost:3000/#' +
querystring.stringify({
access_token: access_token,
refresh_token: refresh_token
}));
} else {
res.redirect('/#' +
querystring.stringify({
error: 'invalid_token'
}));
}
});
}
});
app.get('/refresh_token', function(req, res) {
// requesting access token from refresh token
var refresh_token = req.query.refresh_token;
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: { 'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')) },
form: {
grant_type: 'refresh_token',
refresh_token: refresh_token
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token;
res.send({
'access_token': access_token
});
}
});
});
console.log('Listening on 8888');
app.listen(8888);
This is the client code to connect with the Web Playback API:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Spotify listener</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="https://sdk.scdn.co/spotify-player.js"></script>
<script>
window.onSpotifyWebPlaybackSDKReady = () => {
console.log("The Web Playback SDK is ready. We have access to Spotify.Player");
console.log(window.Spotify.Player);
};
async function getToken() {
/**
* Obtains parameters from the hash of the URL
* #return Object
*/
function getHashParams() {
var hashParams = {};
var e, r = /([^&;=]+)=?([^&;]*)/g,
q = window.location.hash.substring(1);
while ( e = r.exec(q)) {
hashParams[e[1]] = decodeURIComponent(e[2]);
}
return hashParams;
}
var params = getHashParams();
access_token = params.access_token;
refresh_token = params.refresh_token;
error = params.error;
if (error) {
alert('There was an error during the authentication');
} else {
if (access_token) {
// render oauth info
console.log("Success ac: " + access_token)
return access_token;
}
}
}
async function waitForSpotifyWebPlaybackSDKToLoad () {
return new Promise(resolve => {
if (window.Spotify) {
resolve(window.Spotify);
} else {
window.onSpotifyWebPlaybackSDKReady = () => {
resolve(window.Spotify);
};
}
});
}
async function waitUntilUserHasSelectedPlayer (sdk) {
return new Promise(resolve => {
let interval = setInterval(async () => {
let state = await sdk.getCurrentState();
if (state !== null) {
resolve(state);
clearInterval(interval);
}
});
});
}
(async () => {
const { Player } = await waitForSpotifyWebPlaybackSDKToLoad();
const token = "TEMPORARY_TOKEN"; //working temporary token
//const token = await getToken(); //I get a token but it does not work
console.log("token: " + token);
const sdk = new Player({
name: "Web Playback SDK",
volume: 1.0,
getOAuthToken: callback => { callback(token); }
}); sdk.on("player_state_changed", state => {
// Update UI with playback state changes
}); let connected = await sdk.connect();
if (connected) {
let state = await waitUntilUserHasSelectedPlayer(sdk);
await sdk.resume();
await sdk.setVolume(0.5); let {
id,
uri: track_uri,
name: track_name,
duration_ms,
artists,
album: {
name: album_name,
uri: album_uri,
images: album_images
}
} = state.track_window.current_track;
console.log(`You're listening to ${track_name} by ${artists[0].name}!`);
}
})();
</script>
</body>
</html>
The debugger shows the error: "TypeError: this._acmeTrack is null"
Any help, hints and of course your time is greatly appreciated!
Handy way to check tokens are working is to go to developer.spotify.com then Console and find any authenticated API call you need to try out then you can paste the token you have and if that works, you at least know a token is valid before spending time figuring out what's wrong!

conversationId - Value can't be NULL

In a Word-addin I'm am trying to fetch data from AAD with the help of ADAL and microsoft.graph. Here is the code:
from app.js
var app = (function () {
"use strict";
window.config = {
instance: 'https://login.microsoftonline.com/',
tenant: '<TENANT>',
clientId: '<CLIENTID>',
redirectUri: '<THE-APP-ADDRESS>',
postLogoutRedirectUri: window.location.origin,
endpoints: {
officeGraph: 'https://graph.microsoft.com',
},
callback: userSignedIn,
popUp: true,
cacheLocation: 'localStorage'
};
function signIn() {
authContext.login();
}
function userSignedIn(err, token) {
console.log('userSignedIn called');
// showWelcomeMessage();
if (!err) {
console.log("token: " + token);
showWelcomeMessage();
}
else {
console.error("error: " + err);
}
}
function showWelcomeMessage() {
var authContext = new AuthenticationContext(config);
var $userDisplay = $(".app-user");
var $signInButton = $(".app-login");
var $signOutButton = $(".app-logout");
// Check For & Handle Redirect From AAD After Login
var isCallback = authContext.isCallback(window.location.hash);
authContext.handleWindowCallback();
if (isCallback && !authContext.getLoginError()) {
window.location = authContext._getItem(authContext.CONSTANTS.STORAGE.LOGIN_REQUEST);
}
and main.js
function getDataFromSelection() {
var baseEndpoint = 'https://graph.microsoft.com';
var authContext = new AuthenticationContext(config);
Office.context.document.getSelectedDataAsync(Office.CoercionType.Text,
function (asyncResult) {
if (asyncResult.status === Office.AsyncResultStatus.Succeeded) {
authContext.acquireToken(baseEndpoint, function (error, token) {
if (error || !token) {
app.showNotification("Ingen token: ", "Du får logga in igen." + error); // + error
}
//var email = authContext._user.userName;
var url = "https://graph.microsoft.com/v1.0/" + config.tenant + "/me";
var html = "<ul>";
$.ajax({
beforeSend: function (request) {
request.setRequestHeader("Accept", "application/json");
},
type: "GET",
url: url,
dataType: "json",
headers: {
'Authorization': 'Bearer ' + token,
}
}).done(function (response) {
html += getPropertyHtml("Namn", response.displayName);
html += getPropertyHtml("Titel", response.jobTitle);
html += getPropertyHtml("Avdelning", response.officeLocation);
html += getPropertyHtml("Telefon jobb", response.businessPhones);
$("#results").html(html);
return postDataToContentControlers(response);
}).fail(function (response) {
// app.showNotification('Inloggningen slutade att fungera!', 'Du får logga ut och prova att logga in igen'); //response.responseText
}).always(function () {
console.log("AJAX is done!!")
})
});
} else {
app.showNotification('Error:', 'Något gick fel. Du får logga in igen.'); //result.error.message
}
}
);
}
On local wordklient it works but on Word online (Office 365 Pro Plus v.1609)
I get this when running the function getDataFromSelection();
Error from console
And right Before I login and i get confirmed and a token:
the parameter ConversationId is handled when you use microsoft-graph to GET mail-messages. Every mail has a conversationId... Why is it complaining about that regarding a GET against https://graph.microsoft.com/v1.0/me ?
Does anyone know how to get around this problem or Point me in the right direction? Thanks =)
EDIT: And I forgot to mention that this works online on Google Chrome but on Microsoft Edge The popup doesn't work at all regarding login Before even fetching any data. Only popup the addin again.

How to return authRequired and WL.Server.invokeHttp value to client side using web services in Adapter based authentication with worklight?

Edit : I am using Adapter based authentication with worklight and angularJs. on click of login button i'm calling submitLogin procedure and pass the username and password in parameter as mention below. my query is after invocation of adapter how i'll return the authRequired value and WL.Server.invokeHttp(input) response simultaneously to the client side. i also mention challenge handler for authentication in login services code
adapter code:
function submitLogin(username, password){
WL.Logger.debug("username: "+username);
var payload = {
"Header": {
"header": {
"myschemeName": "",
"myserviceVersion": "0.00",
"myinternalId": "",
"myexternalId": "",
"mysource": "web",
"mydestination": "test",
"myuserId": ""
}
},
"Body": {
"login": {
"username": username,
"password": password
}
}
}
var input = {
method : 'post',
returnedContentType : 'jsonp',
path: '/mywebservices/login',
headers : {
'Accept-Encoding': 'gzip,deflate',
'Content-Type': 'application/json'
},
body: {
'contentType' : 'application/json',
'content' : payload
}
};
return {authRequired: false, WL.Server.invokeHttp(input);};
}
login services:
angular.module('my.services')
.factory('loginServices', function($http, $q, $rootScope) {
'use strict';
//worklight
var realm = "AdapterAuthRealm";
var securityTest = "Master-Password";
//offline
var offlineAuthed = false;
var tempUser = {};
//user object
var userObj = {};
//login popup
userObj.dialog = false;
//login error message
userObj.authError = "";
//logged in boolean
userObj.loggedIn = null;
var defunct = null;
//change handler
var ch = WL.Client.createChallengeHandler(securityTest);
//first response after protected call
ch.isCustomResponse = function(response){
console.log("challenge handler -- isCustomResponse");
if (!response || !response.responseJSON || response.responseText === null) {
return false;
}
if (typeof(response.responseJSON.authRequired) !== 'undefined'){
return true;
} else {
return false;
}
};
//when isCustomResponse returns true
ch.handleChallenge = function(response){
console.log("challenge handler -- handleChallenge");
var err = response.responseJSON.errorMessage;
var req = (String(response.responseJSON.authRequired) == "true");
if (!req){ //successful login request
console.log("-> login success!");
//create offline auth credentials
createOfflineAuth();
//call the success function of initial adapter call
//ch.submitSuccess();
}
//error message
userObj.authError = "";
if (err != null){
userObj.authError = "* " + err;
}
//login boolean
userObj.loggedIn = !req;
//show login popup
userObj.dialog = req;
//update scope
$rootScope.$apply();
//resolve original function if it exists
if (defunct != null){
defunct.resolve(userObj.loggedIn);
}
};
//** Offline **//
//check if user is online
function checkOnline(){
var def = $q.defer();
WL.Client.connect({
onSuccess: function(){
console.log("** User is online!");
def.resolve(true);
},
onFailure: function(){
console.log("** User is offline!");
def.resolve(false);
},
timeout: 1000
});
return def.promise;
}
//creates an offline authentication object
function createOfflineAuth(){
console.log("creating offline auth");
//encrypt the user object
var encyptedUser = md5(angular.toJson(tempUser));
//save to local storage
localStorage.setItem(tempUser.username, encyptedUser);
//clear tempUser
tempUser = {};
}
//offline login
function offlineLogin(){
userObj.authError = "";
//encrypt the tempuser object
var match = md5(angular.toJson(tempUser));
var savedAuth = localStorage.getItem(tempUser.username);
//check if matching the saved one
offlineAuthed = (savedAuth == match);
console.log("Login successfull: " + offlineAuthed);
//error - mismach
if (!offlineAuthed){
userObj.authError = "* Wrong login details.";
}
//error - if the user has never authenticated with the server
if (savedAuth == null){
userObj.authError = "* You have to go online first.";
}
//login boolean
userObj.loggedIn = offlineAuthed;
//show login popup
userObj.dialog = !offlineAuthed;
return offlineAuthed;
}
//-- APIS to the rest of the app --//
return {
getUser: function(){
return userObj;
},
initUser: function () {
console.log("-> getting user state data");
var def = $q.defer();
checkOnline().then(function (onl){
if (onl){ //online
WL.Client.updateUserInfo({onSuccess: function(){
userObj.loggedIn = WL.Client.isUserAuthenticated(realm);
def.resolve();
}});
} else { //offline
userObj.loggedIn = false;
def.resolve();
}
});
return def.promise;
},
checkUser: function () {
var def = $q.defer();
checkOnline().then(function (onl){
if (onl){ //online
userObj.loggedIn = WL.Client.isUserAuthenticated(realm);
} else { //offline
userObj.loggedIn = offlineAuthed;
}
userObj.dialog = !userObj.loggedIn;
//check success
if (!userObj.loggedIn){
//save the deferred for challengehandler
defunct = def;
} else {
//resolve
def.resolve(true);
}
});
return def.promise;
},
login: function (user,pass){
//promise
var logindef = $q.defer();
//tempuser
tempUser = {username:user, password:pass};
userObj.user = user;
checkOnline().then(function (onl){
if (onl){ //online
console.log("attempting online login");
var options = {
parameters:[user, pass],
adapter:"myAdapter",
procedure:"submitLogin"
};
ch.submitAdapterAuthentication(options,{
onSuccess: function(){
console.log("-> submitAdapterAuthentication onSuccess!");
//update user info, as somehow isUserAuthenticated return false without it
WL.Client.updateUserInfo({onSuccess: function(){
//return promise
logindef.resolve(true);
}});
}
});
} else { //offline
console.log("attempting offline login");
logindef.resolve(offlineLogin());
}
});
return logindef.promise;
}
};
});
I am trying to decrypt your question. It's not clear at all.
However there is already one thing that jumps out.
In your adapter you finished with:
return {authRequired: false, WL.Server.invokeHttp(input);};
You saying authRequired false even before checking if the credentials are valid?
You are supposed to parse the content of the results of WL.Server.invokeHttp(input) inside the adapter, decide if the credentials are valid.
If they are valid use setActiveUser before returning authRequired false.
Don't return the content of WL.Server.invokeHttp(input) to the client. This is meant for the adapter to parse.
See this tutorial: https://developer.ibm.com/mobilefirstplatform/documentation/getting-started-7-1/foundation/authentication-security/adapter-based-authentication/

how to get publish_stream permissions for post on facebook wall?

here is my connection:
window.fbAsyncInit = function () {
FB.init({
appId: "348044465251207",
status: true,
cookie: true,
xfbml: true,
oauth: true
});
FB.Event.subscribe('auth.login', function (response) {
var credentials = { uid: response.authResponse.userID, accessToken: response.authResponse.accessToken };
SubmitLogin(credentials);
}, { perms: 'read_stream,publish_stream,offline_access' });
FB.getLoginStatus(function (response) {
if (response.status === 'connected') {
FB.api('/me', function (response) {
//console.log('Good to see you, ' + response.name + '.');
mail = response.email;
currentName = response.name;
gender = response.gender;
place = response.location;
$.ajax({
url: "/Login/DetailsToDataBase",
type: "POST",
data: { gender: gender, mail: mail, place: place },
success: function (data) {
generalScore = data;
div_element = document.getElementById("userScore");
div_element.innerHTML = "Your score is: " + generalScore;
}
});
});
} //end if
else if (response.status === 'not_authorized') { alert("user is not authorised"); }
else { alert("user is not conntected to facebook"); }
}, { scope: 'read_stream,publish_stream,offline_access' });
function SubmitLogin(credentials) {
$.ajax({
url: "/Login/FacebookLogin",
type: "POST",
data: credentials,
error: function () {
alert("error logging in to your facebook account.");
},
success: function () {
// alert("success log in facebook");
// window.location.reload();
}
});
}
};
(function (d) {
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement('script');
js.id = id;
js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
} (document));
and this is the function to post on user facebook wall:
var params = {};
params['method'] = 'stream.publish';
params['message'] = currentName +' earn '+ score+ '$ in battelship!';
params['name'] = 'BattelShip';
params['description'] = 'let\'s see if you sucsses to break my highlight';
params['link'] = 'https://apps.facebook.com/348044465251207/?fb_source=search&ref=ts&fref=ts';
params['picture'] = 'http://www.israup.net/images/98d0808995e356818a0c016bc1a2a7cc.png';
params['caption'] = 'Try it by Yourself!';
FB.api('/me/feed', 'post', params, function(response) {
if (!response || response.error) {
console.log('Error occured');
} else {
console.log('Published to stream - you might want to delete it now!');
}
});
it post only on my wall (because i am the admin of the app), but for another users it says:
"The user hasn't authorized the application to perform this action"
help me please!!
You need to look at the Login documentation again I think, you're using a parameter in part of your login flow 'perms' which was deprecated over a year ago in favour of 'scope' -
Check the examples that come with the SDK and read the login documentation, though the code might just work if you fix that error, i'd be wary of what other things have changed in the API since the example you're working from was written - you can check what permissions were granted to the access token you're using by calling /me/permissions with that access token

Categories

Resources