good day how to send an email verification on Xamarin after you register an account I'm using this code but in sendEmailVerification it said FirebaseAuth does not define sendEmailVerification
how can I fix this?
private void LoginUser(string email, string password){
if (input_password.Text == reinput_password.Text){
auth.CreateUserWithEmailAndPassword(email, password)
.AddOnCompleteListener(this, this);
auth.sendEmailVerification(email)
.AddOnCompleteListener(this, this);
}
}
SendEmailVerification(Async) is a method on an FirebaseUser instance:
Example (using Xamarin async wrappers):
auth = FirebaseAuth.Instance;
using (var authResult = await auth.CreateUserWithEmailAndPasswordAsync("so#sushi.com", "stackoverflow"))
using (var user = authResult.User)
using (var actionCode = ActionCodeSettings.NewBuilder().SetAndroidPackageName(PackageName,true, "0").Build())
{
await user.SendEmailVerificationAsync(actionCode);
}
my code works but there is something wrong IsEmailVerified always false
var authProvider = new FirebaseAuthProvider(new FirebaseConfig(webapi));
var auth = await authProvider.SignInWithEmailAndPasswordAsync(emailtxt.Text, passwordtxt.Text);
string gettoken = auth.FirebaseToken;
var content = await auth.GetFreshAuthAsync();
var serializedcontnet = JsonConvert.SerializeObject(content);
Preferences.Set("MyFirebaseRefreshToken", serializedcontnet);
if(content.User.IsEmailVerified == false)
{
var action = await App.Current.MainPage.DisplayAlert("Alert", "Your Email not activated,Do You want to Send Activation Code again?!", "Yes","No");
if(action)
{
await authProvider.SendEmailVerificationAsync(gettoken);
}
}
Related
I have this piece of code in C# using InstaSharper to return information of a media id from Instagram.
public async Task<UserSessionData> SignIn(string userName, string password)
{
userSessionData = new UserSessionData();
userSessionData.UserName = "username";
userSessionData.Password = "password";
api = InstaApiBuilder.CreateBuilder()
.SetUser(userSessionData)
.Build();
var loginRequest = await api.LoginAsync();
if (loginRequest.Succeeded && api.IsUserAuthenticated)
{
IResult<InstaUser> userSearch = await api.GetUserAsync(userName);
IResult<InstaMediaList> media = await api.GetUserMediaAsync(userName, PaginationParameters.MaxPagesToLoad(1));
IResult<InstaMedia> mediaInfo = await api.GetMediaByIdAsync("1924613027431050955");
return userSessionData;
}
else
{
return null;
}
}
GetMediaByIdAsync method correctly returns data about the requested media but the Likers and Tags collection is empty. Is there any way to include those data?
Had the same issue, I found the solution.
Try using this code:
var posts = await api.GetUserMediaAsync("username", PaginationParameters.MaxPagesToLoad(Int32.MaxValue)); // If you want to load all of the posts. If not, replace the "Int32.MaxValue" with the amount of posts you want to load
foreach (var post in posts.Value)
{
var likers = await api.GetMediaLikersAsync(post.InstaIdentifier);
foreach (var liker in likers.Value)
{
Console.WriteLine(liker.UserName);
}
}
This works fine for me, try it out, Im sure it will work for you as well.
I have two projects. One is an Identity server 4 who handle users and authentication. The second need to use the first to login and ask for a token to access an API.
When I need to refresh the token I don't now how to handle the new access token. How I can set to the authentification asp dot net core the new token. All the refresh process are made on a AuthorizationHandler.
I tried to modify the claims on identity but doesnt work. I tried to stock access token and refresh token inside my own cookie but I have trouble because when I refresh the token I can only use them at the next request (I didn't achieve to modify the request.cookies only the response.cookies.
public static async Task SetToken(TokenKind token,string value, HttpContext context)
{
context.Response.Cookies.Append(GetTokenCookieName(token), value);
}
public static async Task<string> GetRefreshTokenAsync(HttpContext context)
{
return await SearchToken(TokenKind.Refresh,context);
}
private static async Task<string> SearchToken(TokenKind token, HttpContext context)
{
var tokenName = GetTokenName(token);
var test = context.Request.Cookies;
var apiToken = context.Request.Cookies.FirstOrDefault(x => x.Key == GetTokenCookieName(token)).Value;
if (apiToken == null)
{
// Save token into cookie
var tokenValue = await context.GetTokenAsync(GetTokenName(TokenKind.Access));
await SetToken(TokenKind.Access, tokenValue, context);
var refreshTokenValue = await context.GetTokenAsync(GetTokenName(TokenKind.Refresh));
await SetToken(TokenKind.Refresh, refreshTokenValue, context);
switch (token)
{
case TokenKind.Access:
return tokenValue;
case TokenKind.Refresh:
return refreshTokenValue;
default:
return null;
break;
}
}
else
{
return apiToken;
}
}
private async Task<bool> RefreshToken(AuthorizationFilterContext mvcContext, HttpClient client)
{
var refreshToken = await TokenUtils.GetRefreshTokenAsync(mvcContext.HttpContext);
//await mvcContext.HttpContext.GetTokenAsync("refresh_token");
var variables = new Dictionary<string, string>
{
{ "grant_type", "refresh_token" },
{ "client_id", _configuration["ApplicationOptions:ClientId"] },
{ "client_secret", _configuration["ApplicationOptions:ClientSecret"] },
{ "refresh_token", refreshToken }
};
var content = new FormUrlEncodedContent(variables);
var url = _configuration["ApplicationOptions:AuthorizeServer"] + "/connect/token";
var response = await client.PostAsync(url, content);
if (response.IsSuccessStatusCode == false)
{
var errorString = await response.Content.ReadAsStringAsync();
var errorData = JsonConvert.DeserializeObject<dynamic>(errorString);
return false;
}
var contentAsString = await response.Content.ReadAsStringAsync();
var responseData = JsonConvert.DeserializeObject<dynamic>(contentAsString);
var newAccessToken = (string)responseData.access_token;
var newRefreshToken = (string)responseData.refresh_token;
await TokenUtils.SetAccessToken(newAccessToken, mvcContext.HttpContext);
await TokenUtils.SetRefreshToken(newRefreshToken, mvcContext.HttpContext);
var result = await mvcContext.HttpContext.AuthenticateAsync();
if (result.Succeeded)
{
result.Properties.StoreTokens(new List<AuthenticationToken>
{
new AuthenticationToken
{
Name = OpenIdConnectParameterNames.AccessToken,
Value = newAccessToken
},
new AuthenticationToken
{
Name = OpenIdConnectParameterNames.RefreshToken,
Value = newRefreshToken
}
});
return true;
}
else
{
return false;
}
}
I would like to know what is the good pratice to store (or replace the actual access token) with the .net core authentification. I'm sure I'm not doing it the right way. At the end I want to handle correctly my token and my refresh token for not ask the user to login again. Now with my solution my project will denied the access when it need to refresh the token and next request will be granted (because the cookie need to be resend from the user).
Thank to Ruard van Elburg I found the solution (here's the complete answer)
And that's what I used to replace my tokens:
// Save the information in the cookie
var info = await mvcContext.HttpContext.AuthenticateAsync("Cookies");
info.Properties.UpdateTokenValue("refresh_token", newRefreshToken);
info.Properties.UpdateTokenValue("access_token", newAccessToken);
info.Properties.UpdateTokenValue("expires_at", expiresAt.ToString("o", CultureInfo.InvariantCulture));
await mvcContext.HttpContext.SignInAsync("Cookies", info.Principal, info.Properties);
I'm working on a bot using bot framework. With active directory authentication I managed to get the username . Now I want to get the phone number and logged in user Email ID after authenticated using active directory ?
Below is the code I'm working with.
Authentication
AuthenticationOptions options = new AuthenticationOptions()
{
UseMagicNumber = false,
Authority = Convert.ToString(ConfigurationManager.AppSettings["aad:Authority"]),
ClientId = Convert.ToString(ConfigurationManager.AppSettings["aad:ClientId"]),
ClientSecret = Convert.ToString(ConfigurationManager.AppSettings["aad:ClientSecret"]),
ResourceId = Convert.ToString(ConfigurationManager.AppSettings["aad:ResourceId"]),
RedirectUrl = Convert.ToString(ConfigurationManager.AppSettings["aad:Callback"])
};
await context.Forward(new AuthDialog(new ADALAuthProvider(), options), ResumeAfterLogin, message, context.CancellationToken);
Extracting the data
private async Task ResumeAfterLogin(IDialogContext authContext, IAwaitable<AuthResult> authResult)
{
string tokenstring = string.Empty;
string userName = string.Empty;
var resultToken = await authResult;
string email = string.Empty;
try
{
tokenstring = resultToken.AccessToken;
userName = resultToken.UserName;
MyGlobalVariables.EmailID = "";
MyGlobalVariables.username = userName;
if (null != tokenstring && string.Empty != tokenstring)
{
authContext.UserData.SetValue<string>("AccessToken", tokenstring);
authContext.UserData.SetValue<string>("userName", userName);
await authContext.PostAsync($"*info: you are logged in as {userName}*");
authContext.Call(new RootDialog(), this.ResumeAfterOptionDialog);
}
}
catch (Exception ex)
{
authContext.Wait(MessageReceivedAsync);
throw ex;
}
finally
{
}
}
You can get phone numbers and emails of logged in users by accessing the Microsoft AAD Graph API. For example:
public async Task<User> GetMe()
{
var graphClient = GetAuthenticatedClient();
var me = await graphClient.Me.Request().GetAsync();
return me;
}
A full sample can be found here.
I am currently working on a Xamarin Studio Forms application where I both get and post data with REST-api calls. I do this with both messaging and also by storing login credentials. With my current frontend C# and backend PHP setup I can successfully login users, but now i wish to add security to the whole thing.
Right now to see if a your user credentials are correct I do this:
static public async Task<JObject> LoginUser(string Email, string Password)
{
var httpClientRequest = new HttpClient();
try
{
var result = await httpClientRequest.GetAsync(”http://myURL.com/Signingup/Login.php?Email=" + Email + "&Password=" + Password);
var resultString = await result.Content.ReadAsStringAsync();
var jsonResult = JObject.Parse(resultString);
return jsonResult;
}
catch {
return null;
}
}
And I retrieve it with this PHP code:
<?php
class ConnectionInfo
{
public $conn;
public function GetConnection() {
$this->conn = mysqli_connect(”server”, ”user”,”pass”, ”db”) or die(mysqli_error($mysql_pekare));
}
}
$connectionInfo = new ConnectionInfo();
$connectionInfo->GetConnection();
if (!$connectionInfo->conn)
{
echo 'No Connection';
}
else
{
$Email = $_GET['Email'];
$Password = $_GET['Password'];
$query = "SELECT * FROM Login WHERE Email = '$Email' AND Password = '$Password'";
$stmt = mysqli_query($connectionInfo->conn, $query);
if (!$stmt)
{
echo 'Query failed';
}
else
{
$contacts = array();
while ($result = mysqli_fetch_array($stmt))
{
$contact = array("Email" => utf8_encode ($result['Email']),"Password" => utf8_encode ($result['Password']),
"UserID" => ($result['UserID']));
array_push($contacts, $contact);
}
echo json_encode ($contact, JSON_PRETTY_PRINT);
}
}
?>
This works and I can successfully retrieve the data in my C# application and successfully login a user. But now the security aspects comes in. How would I secure this?
I read briefly about ”hashing” but also about creating ”sessiontokens” but I am unsure on which way to go/which way would be the best and most secure approach.
When I looked at an old example with ”Parse” I saw that they added a App-ID key and a REST Api key with all their httpClientRequest calls, looking like this:
httpClientRequest.DefaultRequestHeaders.Add ("X-Parse-Application-Id", appIdString);
httpClientRequest.DefaultRequestHeaders.Add ("X-Parse-REST-API-Key", apiKeyString);
Could this be a good way to approach it? If it is and I add these headers to my GetAsync call, what would I then need to do with my PHP code in order to retrieve the call?
This is the signup code:
C#
static public async Task<JObject> SignupUser(string Email, string Password)
{
var httpClientRequest = new HttpClient();
var postData = new Dictionary<string, object>();
try
{
postData.Add("Email", Email);
postData.Add("Password", Password);
var jsonRequest = JsonConvert.SerializeObject(postData);
HttpContent content = new StringContent(jsonRequest, System.Text.Encoding.UTF8, "application/json");
var result = await httpClientRequest.PostAsync("http://url.com/Signup/Signup.php", content);
var resultString = await result.Content.ReadAsStringAsync();
var jsonResult = JObject.Parse(resultString);
return jsonResult;
}
catch {
return null;
}
}
PHP:
<?php
$value = json_decode(file_get_contents('php://input'));
$mysql_pekare= new mysqli ("serv", "user","pass", "db");
if(!empty($value)) {
$stmt = $mysql_pekare->prepare("INSERT INTO Login (`Email`, `Password`) VALUES(?,?)");
$stmt->bind_param("ss", $value->Email, $value->Password);
printf(mysqli_insert_id());
$stmt->execute();
if(!empty($stmt)) {
session_start();
$contacts = array();
$id = mysqli_insert_id();
$contact = array("UserID" => ($stmt->insert_id));
array_push($contacts, $contact);
echo json_encode ($contact, JSON_PRETTY_PRINT);
$stmt->close();
$mysql_pekare->close();
}
}
}
?>
I'm having troubles .NET Core Web API app authentication.
I want to:
1) Authenticate user with Google on Mobile App (currently iOS)
2) Using this authentication, create user record in database using AspNetCore.Identity and Entity Framework Core
3) Using same authentication, call Google Calendar API from .NET Core server
So far I figured out how to implement 1 and 3, but can't wrap my head around number 2.
My understanding is that to sign in user authenticated with third-party, due to documentation, you need to use SignInManager instance method ExternalLoginSignInAsync. It takes two arguments:
login provider (should be simple stirng as "Google") and unique provider key. My problem is that I can't find anywhere where can I get one.
Here is the list of all things I receive from Google Sign In result on mobile app:
Here is the method I try to call in.
// POST api/signup
[HttpPost]
public async Task<bool> Post([FromBody]string authorizationCode, [FromBody]string userId)
{
var tokenFromAuthorizationCode = await GetGoogleTokens(userId, authorizationCode);
var result = await signInManager.ExternalLoginSignInAsync(
"Google", tokenFromAuthorizationCode.IdToken, false);
if (result.Succeeded)
return true;
var externalLoginInfo = new ExternalLoginInfo(
ClaimsPrincipal.Current, "Google", tokenFromAuthorizationCode.IdToken, null);
return await SignInUser(externalLoginInfo);
}
private async Task<bool> SignInUser(ExternalLoginInfo info)
{
var newUser = new AppUser { Email = "test#test.com", UserName = "TestUser" };
var identResult = await userManager.CreateAsync(newUser);
if (identResult.Succeeded)
{
identResult = await userManager.AddLoginAsync(newUser, info);
if (identResult.Succeeded)
{
await signInManager.SignInAsync(newUser, false);
return true;
}
}
return false;
}
private async Task<TokenResponse> GetGoogleTokens(string userId, string authorizationCode)
{
TokenResponse token;
try
{
// TODO: Save access and refresh token to AppUser object
token = await authFlow.Flow.ExchangeCodeForTokenAsync(
userId, authorizationCode, "http://localhost:60473/signin-google", CancellationToken.None);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
return token;
}
My question is: is it a correct path if you're building authentication via REST API, and if so, where could I get Google's provider key?
Thanks in advance.
Well apparently, provider key is just user id from Google.
Here is the solution that worked for me:
[HttpPost]
public async Task<AppUser> Post([FromBody]GoogleSignInCredentials credentials)
{
// 1. get user id from idToken
var oauthService = new Oauth2Service(new BaseClientService.Initializer { ApiKey = "{your api key}" });
var tokenInfoRequest = oauthService.Tokeninfo();
tokenInfoRequest.IdToken = credentials.IdToken;
var userInfo = await tokenInfoRequest.ExecuteAsync();
// 2. get access_token and refresh_token with new id and authorization code
var tokenFromAuthorizationCode = await GetGoogleTokens(userInfo.UserId, credentials.AuthorizationCode);
// 3. check if user exists
var result = await _signInManager.ExternalLoginSignInAsync(
"Google", userInfo.UserId, false);
if (result.Succeeded)
return await _userManager.FindByEmailAsync(userInfo.Email);
// 4. create user account
var externalLoginInfo = new ExternalLoginInfo(
ClaimsPrincipal.Current, "Google", userInfo.UserId, null);
// 5. fetch user
var createdUser = await SignInUser(externalLoginInfo, userInfo.Email);
if (createdUser != null)
{
createdUser.GoogleAccessToken = tokenFromAuthorizationCode.AccessToken;
createdUser.GoogleRefreshToken = tokenFromAuthorizationCode.RefreshToken;
var updateResult = await _userManager.UpdateAsync(createdUser);
if (updateResult.Succeeded)
return createdUser;
return null;
}
return null;
}
private async Task<AppUser> SignInUser(ExternalLoginInfo info, string email)
{
var newUser = new AppUser { Email = email, UserName = email };
var identResult = await _userManager.CreateAsync(newUser);
if (identResult.Succeeded)
{
identResult = await _userManager.AddLoginAsync(newUser, info);
if (identResult.Succeeded)
{
await _signInManager.SignInAsync(newUser, false);
return await _userManager.FindByEmailAsync(email);
}
}
return null;
}
private async Task<TokenResponse> GetGoogleTokens(string userId, string authorizationCode)
{
return await _authFlow.Flow.ExchangeCodeForTokenAsync(
userId, authorizationCode, "http://localhost:60473/signin-google", CancellationToken.None);
}