Facebook login manual flow with error - facebook

After I dealt with this error a verified many fori and all mentioned that the solution for this error would be having in Facebook settings the “Valid OAuth Redirect URIs” set to “https://www.facebook.com/connect/login_success.htm”, what it is, so that is not the issue. Furthermore, all solutions found are too old and use obsolete components.
Said that using Xamarin Forms I’m trying to do the manual flow to login into Facebook as described in “https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow”.
The code is:
using Authentication.ViewModels;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Authentication
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class FacebookProfilePage : ContentPage
{
private string ClientId = "910688099117930";
public FacebookProfilePage()
{
InitializeComponent();
var apiRequest =
"https://www.facebook.com/dialog/oauth?client_id="
+ ClientId
+ "&display=popup&response_type=token&redirect_uri=http://www.facebook.com/connect/login_success.html"
+ "&state=state123abc";
var webView = new WebView
{
Source = apiRequest,
HeightRequest = 1
};
webView.Navigated += WebViewOnNavigated;
Content = webView;
}
private async void WebViewOnNavigated(object sender, WebNavigatedEventArgs e)
{
var accessToken = ExtractAccessTokenFromUrl(e.Url);
if (accessToken != "")
{
var vm = BindingContext as FacebookViewModel;
await vm.SetFacebookUserProfileAsync(accessToken);
Content = MainStackLayout;
}
}
private string ExtractAccessTokenFromUrl(string url)
{
if (url.Contains("access_token") && url.Contains("&expires_in="))
{
var at = url.Replace("https://www.facebook.com/connect/login_success.html#access_token=", "");
if (Device.OS == TargetPlatform.WinPhone || Device.OS == TargetPlatform.Windows)
{
at = url.Replace("http://www.facebook.com/connect/login_success.html#access_token=", "");
}
var accessToken = at.Remove(at.IndexOf("&expires_in="));
return accessToken;
}
return string.Empty;
}
}
}
Please, notice that this is a open code, found in “https://github.com/HoussemDellai/Facebook-Login-Xamarin-Forms”, which historically has proven itself to work fine.
The URL that I send to login is: “https://www.facebook.com/v3.0/dialog/oauth?client_id=910688099117930&response_type=token&redirect_uri=http://www.facebook.com/connect/login_success.html”. I always get the error message: “Not Logged In: You are not logged in. Please login and try again.”.
Can anyone tell me what’s wrong here?
And before any comment, yes, I’ll delete this App Id as soon as the problem is solved and change it for a new one 😊

Related

Trying to force a user after login to change password

I'm trying to force an authenticated user to change password based on a database Boolean flag. I have used asp.net core resource filter to do that. When ChangePassword flag is on I'm hitting this error. If the ChangePassword flag is is false, application doesn't encounter any error.
InvalidOperationException: If an IAsyncResourceFilter provides a result value by setting the Result property of ResourceExecutingContext to a non-null value, then it cannot call the next filter by invoking ResourceExecutionDelegate.
My codes are as follows -
public class ChangePasswordFilter: IAsyncResourceFilter
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly IUrlHelperFactory _urlHelperFactory;
public ChangePasswordFilter(UserManager<ApplicationUser> userManager, IUrlHelperFactory urlHelperFactory)
{
_userManager = userManager;
_urlHelperFactory = urlHelperFactory;
}
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
{
var HttpContext = context.HttpContext;
var urlHelper = _urlHelperFactory.GetUrlHelper(context);
var redirectUrl = urlHelper.Page("/UserManagement/ChangePassword");
var currentUrl = context.HttpContext.Request.Path;
if (redirectUrl != currentUrl)
{
var user = await _userManager.GetUserAsync(context.HttpContext.User);
if (user?.ChangePassword ?? false)
{
//context.Result = new RedirectResult(redirectUrl);
context.Result = new RedirectToActionResult("ChangePassword", "UserManagement", new { ReturnUrl = HttpContext.Request.Path });
}
}
await next();
}
And in startup.ConfigureServices
services.AddScoped<ChangePasswordFilter>();
services.AddMvc(o =>
{
o.Filters.Add(typeof(ChangePasswordFilter));
});
This example is taken from this answer
Force user change password when loading any webpage
Any help appreciated.
Thanks.
The link you referenced is for a question on asp.net core 2.0. There are many differences between asp.net core 2.0 and asp.net core 5.0.
However, the error message is quite clear. You are invoking the ResourceExecutionDelegate after setting the ResourceExecutingContext Result property to a non-null value.
I'm not too familiar with ResourceFilters but what happens if you replace await next(); with return;?
I was having the same issue, while trying to implement this same code.
I did add return; after context.Result, and my code is working fine.
My code:
context.Result = new RedirectResult(redirectUrl);
return;
Hope you find this helpful.

Invalid Credential When Sign In Facebook SDK To Firebase/Unity

I try to implement Facebook Authentication on my Unity project. So, after experimenting a few things i could make the Email Authentication works fine. But, when i tried to implement the Facebook Authentication it said "Invalid Credential". Here's my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase.Auth;
using Facebook.Unity;
public class facebookAuth : MonoBehaviour
{
private void Awake() {
FB.Init(initCallBack,OnUnityHide);
}
void initCallBack(){
if(!FB.IsInitialized)
FB.ActivateApp();
}
void OnUnityHide(bool show){
if(show)
FB.ActivateApp();
}
public void facebookLogin(){
if(FB.IsLoggedIn){
FB.LogOut();
}
var perms = new List<string>(){"email","public_profile"};
FB.LogInWithReadPermissions(perms,facebookResult);
}
void facebookResult(ILoginResult result){
if(FB.IsLoggedIn){
AccessToken token = result.AccessToken;
Credential credential = FacebookAuthProvider.GetCredential(token.TokenString);
firebaseFacebook(credential);
}
}
void firebaseFacebook(Credential token){
FirebaseAuth.DefaultInstance.SignInWithCredentialAsync(token).ContinueWith(task=>{
if(task.IsCanceled){
Firebase.FirebaseException e = task.Exception.Flatten().InnerExceptions[0] as Firebase.FirebaseException;
errorMessage("Canceled : ",(AuthError)e.ErrorCode);
}
if(task.IsFaulted){
Firebase.FirebaseException e = task.Exception.Flatten().InnerExceptions[0] as Firebase.FirebaseException;
errorMessage("Faulted : ",(AuthError)e.ErrorCode);
}
Debug.Log(task.Result.DisplayName + " " + task.Result.UserId);
});
}
void errorMessage(string str, AuthError error)
{
string msg = error.ToString();
print(str+msg);
}
}
Your code looks correct to my reading. Make sure Facebook is enabled in the Firebase Console and the proper credentials have been filled out:
(I forget this all the time, especially if I have to enter things like the App Secret).
If this doesn't help, it would be useful to have any additional logging (or a copy of the error message) if possible.
--Patrick

Xamarin.Auth: Using Facebook oauth, how to redirect to my app?

I've just started using Xamarin.Auth and I want to enable Facebook login via oauth.
Here is my config:
public static string ClientId = "client id";
public static string ClientSecret = "client secret";
public static string Scope = "email";
public static string AuthorizeUrl = "https://m.facebook.com/dialog/oauth";
public static string RedirectUrl = "https://www.facebook.com/connect/login_success.html";
public static string AccessTokenUrl = "https://m.facebook.com/dialog/oauth/token";
Code for initiating the authentication:
public class AuthenticationPageRenderer : PageRenderer
{
public override void ViewDidAppear(bool animated)
{
base.ViewDidAppear (animated);
var auth = new OAuth2Authenticator (
Constants.ClientId,
Constants.ClientSecret,
Constants.Scope,
new Uri (Constants.AuthorizeUrl),
new Uri (Constants.RedirectUrl),
new Uri (Constants.AccessTokenUrl)
);
auth.Completed += OnAuthenticationCompleted;
PresentViewController (auth.GetUI (), true, null);
}
async void OnAuthenticationCompleted (object sender, AuthenticatorCompletedEventArgs e)
{
Debug.WriteLine ("AUTH Completed!");
if (e.IsAuthenticated) {
}
}
}
Seems to work fine, but instead of redirecting the user to https://www.facebook.com/connect/login_success.html, I want to redirect him back to my app again. Any help much appreciated!
Best,
Sascha
You can "redirect back" to your app again by simply invoking your own method to display the app's page you want to show to your user like this.
async void OnAuthenticationCompleted (object sender, AuthenticatorCompletedEventArgs e)
{
Debug.WriteLine ("AUTH Completed!");
if (e.IsAuthenticated) {
//invoke the method that display the app's page
//that you want to present to user
App.SuccessfulLoginAction.Invoke();
}
}
In your App.cs
public static Action SuccessfulLoginAction
{
get
{
return new Action(() =>
{
//show your app page
var masterDetailPage = Application.Current.MainPage as MasterDetailPage;
masterDetailPage.Detail = new NavigationPage((Page)Activator.CreateInstance(typeof(MainPage)));
masterDetailPage.IsPresented = false;
});
}
}
Assuming that MainPage is the page you wanted to show after successful login. I am using Xamarin.Forms with MasterDetailPage to display pages in my example which maybe different from your app but the concept is the same.
Just call DismissViewController (true, null) in your OnAuthenticationCompleted method. Or use the async equivalent:
async void OnAuthenticationCompleted(object sender, AuthenticatorCompletedEventArgs e)
{
Debug.WriteLine("AUTH Completed!");
await DismissViewControllerAsync(true);
if (e.IsAuthenticated)
{
}
}

Facebook share in wp8 App

I need to share a message on Facebook in my windows phone App by clicking share button. when click share button , if user has not logged in to Facebook, first we redirect to log in screen and then need to ask permission to publish.
public partial class FacebookLoginPage : PhoneApplicationPage
{
string uriToLaunch ;
// Create a Uri object from a URI string
Uri uri = null;
public FacebookLoginPage()
{
InitializeComponent();
uriToLaunch = #"fbconnect://authorize?client_id={AppID}&
scope=public_profile,publish_actions,read_stream&
redirect_uri=msft-{ProductId}%3a%2f%2fauthorize";
uri = new Uri(uriToLaunch);
this.Loaded += FacebookLoginPage_Loaded;
}
private void FacebookLoginPage_Loaded(object sender, RoutedEventArgs e)
{
DefaultLaunch();
}
// Launch the URI
async void DefaultLaunch()
{
// Launch the URI
var success = await Windows.System.Launcher.LaunchUriAsync(uri);
if (success)
{
// URI launched
}
else
{
// URI launch failed
}
}
}
I used above code , but permission screen not appears for publish. Output was as follows.
I followed example and used an AppId, then it works well. I feel that there is special configuration in Facebook App side . Please help me If anyone have idea about it.

How does REST authentication work for client-side apps?

I'm trying to design my first public API, and I'm trying to learn how REST works with authentication, especially in the context of completely client-side apps using js-frameworks, e.g., angularJS.
Say you have a client which is a browser application (i.e., HTML, JS, CSS only) served as static files from something like nginx using a javascript framework to consume a REST service from, e.g. something that requires a secret access key that's used to create a signature for each request to the service, something like Amazon S3.
In terms of authentication in this scenario, where you don't have a server-side application, how would the secret access key be handled, i.e., how do you get it, where do you store it, etc.? It would seem like a horrible security situation to serve the key for each request (even if it only happens once to bootstrap the application).
And even if you do have a light server-side application--how do you securely inform the client (which still calls the authenticated 3rd party API itself) what the signature should be for every request it could possibly make? I'm very confused by how this is supposed to be designed from either end.
I've done a few AngularJS apps and the way that I've found is to use an HttpModule like this one:
using System;
using System.Net.Http.Headers;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Web;
namespace YourSolution.WebApp.Modules
{
public class BasicAuthenticationHttpModule : IHttpModule
{
public BasicAuthenticationHttpModule()
{
}
public void Init(HttpApplication context)
{
context.AuthenticateRequest += OnApplicationAuthenticateRequest;
context.EndRequest += OnApplicationEndRequest;
}
private static void SetPrincipal(IPrincipal principal)
{
Thread.CurrentPrincipal = principal;
if (HttpContext.Current != null)
{
HttpContext.Current.User = principal;
}
}
private static bool CheckPassword(
string username, string password)
{
return username == password;
}
private static void AuthenticateUser(string credentials)
{
try
{
var encoding = Encoding.GetEncoding(
"iso-8859-1");
credentials = encoding.GetString(
Convert.FromBase64String(credentials));
var separator = credentials.IndexOf(':');
var name = credentials.Substring(0, separator);
var password = credentials.Substring(separator + 1);
var validated = CheckPassword(name, password);
if (!validated) return;
var identity = new GenericIdentity(name);
SetPrincipal(new GenericPrincipal(identity, null));
}
catch (FormatException)
{
}
}
private static void OnApplicationAuthenticateRequest(
object sender, EventArgs e)
{
var request = HttpContext.Current.Request;
var authHeader = request.Headers["Authorization"];
if (authHeader == null) return;
var authHeaderVal = AuthenticationHeaderValue.Parse(authHeader);
if (authHeaderVal.Scheme.Equals(
"basic",
StringComparison.OrdinalIgnoreCase)
&& authHeaderVal.Parameter != null)
{
AuthenticateUser(authHeaderVal.Parameter);
}
}
private static void OnApplicationEndRequest(
object sender, EventArgs e)
{
var response = HttpContext.Current.Response;
if (response.StatusCode == 401)
{
//response.Headers.Add(
// "WWW-Authenticate",
// string.Format("Basic realm=\"{0}\"", Realm));
}
}
public void Dispose()
{
}
}
}
The most important part is inside CheckPassword method, there is where you should validate the credentials.
Another point is this line response.Headers.Add("WWW-Authenticate", string.Format("Basic realm=\"{0}\"", Realm)); if you don't comment this line, the classic login requested form will show up, and if you do comment this line you have to catch the 401 error in your requests.
If you want to know about realm: What is the “realm” in basic authentication.
Plus, you will need to register the module in your web.config file:
<system.webServer>
<modules>
<add
name="BasicAuthenticationHttpModule"
type="YourSolution.WebApp.Modules.BasicAuthenticationHttpModule" />
</modules>
</system.webServer>
Then I've added these two methods to deal with the authentication token:
// u: username; p: password
CreateBasicAuthenticationToken = function (u, p) {
var t = u + ':' + p;
var hat = btoa(t);
window.sessionStorage.setItem('basicauthtoken', 'basic ' + hat);
};
DestroyBasicAuthenticationToken = function () {
window.sessionStorage.removeItem('basicauthtoken');
};
The btoa method: The btoa() method of window object is used to convert a given string to a encoded data (using base-64 encoding) string.. Taken from: http://www.w3resource.com/javascript/client-object-property-method/window-btoa.php.
And last I've added the authtoken to the request header using the beforeSend:
$.ajax({
type: 'GET',
url: 'your url',
beforeSend: function (xhr) {
window.sessionStorage.getItem('basicauthtoken');
}
}).done(function (data, textStatus, xhr) {
//...
});
Please do note using jQuery outside an angular directive is not recommended, AngularJS best practices dictates jQuery code must be always placed inside a directive.
Hope it helps.