How can i implement forget password link in my project? - asp.net-core

I have an existing project in asp.net core 2.1 mvc. In the login page, I added forget password link and I wanna make like this thing; When user click this link, other page appear then user entered own email adress and click send buton then password reset link gonna user's email when user click password reset link user entered new password and confirm new password. How can i do this. There are so many resource but generaly in .net core identity but I dont use identity.

You can use session to reset the password.
The bakend
public IActionResult ForgetPassword()
{
//email: send a random code and save it in a session
HttpContext.Session.SetString("randomcode",new Random().Next(1000,10000).ToString());
return View();
}
[HttpPost]
public IActionResult ForgetPassword(string password,string randomCode)
{
//if the Vertification Code is not equals to the randomcode, return fail
if (randomCode != HttpContext.Session.GetString("randomcode"))
{
return View();
}
//update database
return View("index");
}
Give the new password in this form.
<form action="/home/ForgetPassword" method="post">
Password :<input type="text" name="password" value="" />
Confirm Password :<input type="text" name="confirm_password" value="" />
Vertification Code: <input type="text" name="randomCode" value="" />
<input type="submit" name="reset" value="reset"
onclick="Confirm(event)"/>
</form>
javascript
<script>
function Confirm(e) {
var passw = document.getElementsByName('password')[0].value
var confirmPassw = document.getElementsByName('confirm_password')[0].value
if (passw != confirmPassw)
e.preventDefault()
}
</script>

Related

Oppeniddict - How to skip logout prompt?

I am using velusia sample, I want the client app to skip the log out prompt page, is there any specific way to achieve this, or should I implement it my self ?
How you handle logout requests is up to you. To trigger a redirection to the client application (when a post_logout_redirect_uri is set) without displaying a consent form, trigger an ASP.NET Core Logout operation pointing to OpenIddict:
// Returning a SignOutResult will ask OpenIddict to redirect the user agent
// to the post_logout_redirect_uri specified by the client application or to
// the RedirectUri specified in the authentication properties if none was set.
return SignOut(
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
properties: new AuthenticationProperties
{
RedirectUri = "/"
});
That said, I wouldn't recommend doing that: not requiring user consent or a form of anti-forgery protection - the id_token_hint can help, use AuthenticateAsync() to retrieve the principal from it - may make targeted DOS attacks possible.
According to your description, I suggest you could try to set a js code to automatically click the logout button in the server side.
More details, you could refer to below codes:
Modify the server's logout view as below:
#using Microsoft.Extensions.Primitives
<div class="jumbotron">
<h1>Log out</h1>
<p class="lead text-left">Are you sure you want to sign out?</p>
<form asp-controller="Authorization" asp-action="Logout" method="post">
#* Flow the request parameters so they can be received by the LogoutPost action: *#
#foreach (var parameter in Context.Request.HasFormContentType ?
(IEnumerable<KeyValuePair<string, StringValues>>) Context.Request.Form : Context.Request.Query)
{
<input type="hidden" name="#parameter.Key" value="#parameter.Value" />
}
<input class="btn btn-lg btn-success" id="Confirm" name="Confirm" type="submit" value="Yes" />
</form>
</div>
#section scripts{
<script>
$(document).ready(function() {
console.log("Fired");
document.getElementById("Confirm").click();
});
</script>
}
You can also change the HTTP method to GET instead of POST based on Velusia sample:
[HttpGet("logout")]
public async Task<IActionResult> LogoutPost()
{
await HttpContext.SignOutAsync(Clients.CmsApp);
await HttpContext.SignOutAsync(OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
return SignOut(
authenticationSchemes: OpenIddictServerAspNetCoreDefaults.AuthenticationScheme,
properties: new AuthenticationProperties
{
RedirectUri = "/"
});
}

How to get fresh information whether the user is logged in?

In this particular case I am only interested in getting info whether the user is logged in or not.
Following the answers How to enable/disable elements depending whether the user is logged in or not? I can fetch this information but there is one odd problem.
I use Blazor demo app which displays provided "LoginDisplay.razor" component at top, my own page uses following code:
#code {
protected override async Task OnInitializedAsync()
{
Console.WriteLine("Init");
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var authenticated = authState.User.Identity?.IsAuthenticated ?? false;
Console.WriteLine($"We are {authenticated}");
}
}
I have three steps when using this app:
I start the app, I am not logged in, "LoginDisplay" shows "log in" prompt and my code prints I am not authenticated -- good
I click on "log in", I log in, I am redirected back to my page -- "LoginDisplay" now shows my name, yet my code still prints I am not authenticated (this incorrect printout happens when using "NavMenu.razor" but it is fine when when using "Index.razor" -- see update below)
I hit F5 (reload the page) -- "LoginDisplay" shows my name, and the code prints I am authenticated -- as expected
So step (2) is problematic -- I should get the info I am logged in (because I am), and obviously "LoginDisplay" is capable of realizing this fact. So what logic should I add to my code that it too would show I am logged in?
Update After #enet reply I realized the outcome of the step (2) depends where you put this code -- if it placed in "NavMenu.razor" right after logging in the printout states you are not authorized. When I put the same code in "Index.razor" (home page) the printout correctly states I am logged in.
I can see that rendering "NavMenu" is almost immediate, while "Index" is rendered after some pause. So the problem is more "how to get fresh authentication info regardless the page is used?".
The following code describes how you can display your message in the MainLayout component:
<LoginDisplay />
<div>IsAuthenticated: #authenticated.ToString()</div>
#code {
bool authenticated;
[CascadingParameter]
private Task<AuthenticationState> authenticationStateTask {get; set;}
protected override async Task OnInitializedAsync()
{
Console.WriteLine("Init");
var authState = await authenticationStateTask;
var user = authState.User;
authenticated = user.Identity?.IsAuthenticated ?? false;
Console.WriteLine($"We are {authenticated}");
}
}
Note that the above code is executed only when the MainLayout component is initialized. In order to refresh the display of the authenticated message,
we need to executed the code once more. This may be achieved by doing the following:
In the Authentication component add to the RemoteAuthenticatorView component instance the event handler attribute OnLogInSucceeded that is called after the user has logged in, like this:
<RemoteAuthenticatorView Action="#Action" OnLogInSucceeded="RefreshMain" />
Add the event handler RefreshMain
private void RefreshMain()
{
NavigationManager.NavigateTo("mainlayout");
}
The event handler code simply redirect to the MainLayout
Add #inject directive for the NavigationManager, like this:
#inject NavigationManager NavigationManager;
Note that instead of the code above you can simply use the AuthorizeView component like this:
<LoginDisplay />
<div>
<AuthorizeView>
<Authorized>
<div>#context.User.Identity.IsAuthenticated</div>
</Authorized>
<NotAuthorized>
<div>#context.User.Identity.IsAuthenticated</div>
</NotAuthorized>
</AuthorizeView>
</div>
Update
You don't typically use AuthenticationStateProvider directly. Use the AuthorizeView component or Task approaches described later in this article. The main drawback to using AuthenticationStateProvider directly is that the component isn't notified automatically if the underlying authentication state data changes.
Source...
Don't bother yourself too much about rendering. Ordinarily, there is no issue unless your code re-render endlessly.
Anyhow, the following code sample describes how you should really do that:
Reverse the code in the Authentication component to its default state
Change the code you added in the MainLayout to the following
#inherits LayoutComponentBase
#inject AuthenticationStateProvider AuthenticationStateProvider
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4 auth">
<LoginDisplay />
<div>IsAuthenticated: #authenticated.ToString()</div>
<a href="https://learn.microsoft.com/aspnet/"
target="_blank">About</a>
</div>
<div class="content px-4">
#Body
</div>
</div>
</div>
#code {
private bool authenticated;
protected override void OnInitialized()
{
Task<AuthenticationState> _currentAuthenticationStateTask;
AuthenticationStateProvider.AuthenticationStateChanged +=
OnAuthenticationStateChanged;
_currentAuthenticationStateTask =
AuthenticationStateProvider.GetAuthenticationStateAsync();
OnAuthenticationStateChanged(_currentAuthenticationStateTask);
}
private void OnAuthenticationStateChanged
(Task<AuthenticationState> authenticationStateTask)
{
_ = InvokeAsync(async () =>
{
var authState = await authenticationStateTask;
var user = authState.User;
authenticated = user.Identity?.IsAuthenticated ?? false;
StateHasChanged();
});
}
}

Google script HTML api can´t process file upload field

I am trying to create a simple web app in google scripts with the HTML api.
code.gs
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function processForm(formObject) {
var formBlob = formObject.myFile;
var driveFile = DriveApp.createFile(formBlob);
return driveFile.getUrl();
}
index.html
<script>
function updateUrl(url) {
var div = document.getElementById('output');
div.innerHTML = 'Got it!';
}
</script>
<form id="myForm">
<input name="myFile" type="file" />
<input type="button" value="Submit"
onclick="google.script.run
.withSuccessHandler(updateUrl)
.processForm(this.parentNode)" />
</form>
<div id="output"></div>
The form fails to submit. I´m using google chrome Versión 30.0.1599.101 m
This appears in the console: Uncaught NetworkError: Form submission failed.
Here is the app: https://script.google.com/d/1yrgM20n1ZI99bChN2qtQWgGck36OccLN3A16Gn7tCPvsJw0EcK_ql7C5/edit?usp=sharing
Maybe you should add encoding="multipart/form-data" attribute to form tag.
If not solved already – did you try changing the input type from "button" to "submit"? On top of that I'd also try giving it another value than "Submit" since that might interfere with the actual submit parameter.

Save password prompt disappears when changing location

I'm running a login form, which - in case of success - forwards the user to a specific page via JS location.href. The browsers correctly recognize the form as a login form and offer to save the password. Now only in Google Chrome, the prompt disappears once the location changes. So the prompt is visible for just a split second, making it impossible to save the password.Is there any solution for this? Refreshing after login success is a common thing, so there should be a way to fix this..
Edit:
This is what the form looks like:
<form id="loginform" action="process.php" target="processframe" method="POST">
<input id="login_name" name="name" type="text" placeholder="Username"><br>
<input id="login_password" name="password" type="password" placeholder="Password"><br>
<button>Submit</button>
</form>
<iframe src="" id="processframe" name="processframe" style="display:none;"></iframe>
So the request is processed in an iframe. process.php then calls a javascript function:
window.setTimeout("parent.loginsuccess()", 1000);
The loginsuccess() function:
function loginsuccess()
{
location.href="/home.php";
}

Multi friend selector and authentication dialog in PageTab app

i have created a page tab app for which i have set all the parameters under Auth Dialog in the app settings.
Now when i send a friend request through my app, and my friend clicks on the app request, he is able to see the authentication box describing the app and the permissions requested etc.
But if anyone visits my page on which i have added the app, and clicks on the app from there, it directly takes the user to the page tab without displaying the auth box.
Is this how it is supposed to work from a page? is it possible to display the auth box for a user coming to the app from a page?
Secondly, i have added a multi friend selector which opens by default in a popup as it is supposed to.
Is it possible to display it in the page itself instead of a popup?
I tried adding the display: 'page' option but it din work.
I have used the same code from : https://developers.facebook.com/docs/reference/dialogs/requests/
...
<body>
<div id="fb-root"></div>
<p>
<input type="button"
onclick="sendRequestToRecipients(); return false;"
value="Send Request to Users Directly" />
<input type="text" value="User ID" name="user_ids" />
</p>
<p>
<input type="button"
onclick="sendRequestViaMultiFriendSelector(); return false;"
value="Send Request to Many Users with MFS" />
</p>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : XXXXXXXXXXX,
status : true,
cookie : true,
xfbml : true,
oauth : true,
});
};
(function(d){
var js, id = 'facebook-jssdk';
if (d.getElementById(id)) {
return;
}
js = d.createElement('script');
js.id = id;
js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
<script>
function sendRequestToRecipients() {
var user_ids = document.getElementsByName("user_ids")[0].value;
FB.ui({method: 'apprequests',
message: 'My Great Request',
to: user_ids,
}, requestCallback);
}
function sendRequestViaMultiFriendSelector() {
FB.ui({method: 'apprequests',
message: 'My Great Request'
}, requestCallback);
}
function requestCallback(response) {
// Handle callback here
}
</script>
...
Any help in this regard would be very much appreciated.
Is this how it is supposed to work from a page?
Yes. Authenticated referrals don’t work when the app is accessed from a page directly.
is it possible to display the auth box for a user coming to the app from a page?
Of course – analyze the signed_request parameter, and react accordingly (meaning, display the auth dialog yourself, server- or client-side).