# Working with Customers and the login process
Norce Commerce can help when developing login functionality in your front end application. It is not a full-fledged
identity provider but has the ability to store and manage accounts and validate passwords for you. The accounts in Norce
will be associated with the Customer object that can be used for segmentation and specific pricing or offers.
- Read more on that in the [Norce Commerce user documentation](/user-portal/user-landing).
- Check out the examples
in [Postman](https://documenter.getpostman.com/view/2973406/2sA35MzK14#6e0b7951-1d65-4bd5-93a7-1ed0875f984c)
as well.
Note
When using other solutions than Norce's for the authentication functionality, there are other aspects to think about,
you won't need any accounts in Norce, instead you just look up the correct customer in Norce after the login process is
finished.
Use the email address or `CustomerCode` to match an identity from the third party authenticator.
But this document explains the common scenarios for handling the account information in Norce Commerce Services.
[The full Customer Schema](/api-reference/schemas/customer#customer)
details
summary
An example customer (without company)
```JSON
{
"Id": 3710298,
"Key": "264148a6-9c4c-4f7c-827b-8c43ac72a852",
"Code": "cust0043",
"Email": "test0043@tester.com",
"SSN": null,
"FirstName": "Test person 0043",
"LastName": null,
"Phone": null,
"CellPhone": null,
"ReferId": null,
"ReferUrl": null,
"Account": {
"Id": 2095010,
"Key": "f4026524-39b5-43fe-93b3-63da483a7597",
"LoginName": "test0043@tester.com",
"Name": "Test person 0043",
"Roles": [
43
],
"Authorizations": [],
"IsActive": true
},
"Companies": [
{
"Id": 334815,
"Key": "85abed80-7c24-4d26-8f4f-5ad96ca0f222",
"Code": "test0043",
"Name": "Test kund 0043",
"OrgNo": null,
"Phone": null,
"ReferId": null,
"ReferUrl": null,
"DeliveryAddresses": [],
"InvoiceAddress": {
"Id": 11115165,
"CareOf": null,
"Line1": "Testgatan 1",
"Line2": null,
"Zip": "123 45",
"City": "Stockholm",
"CountryId": 0,
"Country": null,
"Region": null,
"IsValidated": false,
"GlobalLocationNo": null,
"ShippingPhoneNumber": null
},
"UseInvoiceAddressAsDeliveryAddress": false,
"Info": [
{
"Id": 267,
"Value": "",
"Code": "A1"
}
],
"PricelistIds": [],
"ParentId": null,
"DeliveryMethodIds": [],
"PaymentMethodIds": [],
"Email": null,
"Flags": [
{
"Id": 118,
"Name": "Bronskund",
"Group": 37,
"IsSelected": true
}
],
"VatNo": null
}
],
"DeliveryAddresses": [],
"InvoiceAddress": {
"Id": 2608019,
"CareOf": null,
"Line1": null,
"Line2": null,
"Zip": null,
"City": null,
"CountryId": 0,
"Country": null,
"Region": null,
"IsValidated": false,
"GlobalLocationNo": null,
"ShippingPhoneNumber": null
},
"Flags": [
{
"Id": 117,
"Name": "Silverkund",
"Group": 37,
"IsSelected": true
}
],
"UseInvoiceAddressAsDeliveryAddress": false,
"Info": [
{
"Id": 237,
"Value": "",
"Code": "Xtra1"
}
],
"PricelistIds": [],
"CrmId": null,
"IsActive": true,
"Created": "/Date(1583484623047+0100)/",
"Updated": "/Date(1583484785267+0100)/"
}
```
```XML
3710298
264148a6-9c4c-4f7c-827b-8c43ac72a852
cust0043
test0043@tester.com
Test person 0043
2095010
f4026524-39b5-43fe-93b3-63da483a7597
test0043@tester.com
Test person 0043
43
true
334815
85abed80-7c24-4d26-8f4f-5ad96ca0f222
test0043
Test kund 0043
11115165
Testgatan 1
123 45
Stockholm
0
false
false
267
A1
118
Bronskund
37
true
2608019
0
false
117
Silverkund
37
true
false
237
Xtra1
true
2020-03-06T09:50:23.047
2020-03-06T09:53:05.267
```
## Create Customer and Account

1. A user choice or action starts the scenario, either from a checkout process or a decision to become a "member" in the
site.
2. After asking for personal information the back-end calls Norce Commerce´s Customer Service
method [RegisterCustomer3](/api-reference/services/customerservice/openapi/customers/registercustomer3).
Norce takes a `password` string, a `Customer` object with an `Account` object (otherwise only the customer is created
and no account functionality is possible) and returns a new `Customer` object with `Account` and its internal `Id`
that should be stored in a persisted way.
3. And a recommended practice is to send a confirmation email at this stage to the customer, or use Norce's build in
functionality for that.
Note
Norce does not validate password strength, this must be done in the backend.
Technical Note
Passwords are stored in Norce after being securely hashed to ensure they cannot be recognized.
## Login

To login, you only need to call
the [LoginPost](/api-reference/services/customerservice/openapi/accounts/loginpost) method
in Norce Commerce, passing in `accountname` and `password`. If credentials is correct a `Customer` object is returned
the user is authenticated and can be added to the session and saved to a cookie. Otherwise, you get an exception. See
api
Reference documentation on the supported errors.
## Re-visit the site
(already logged in)

When a user revisits a site where they are already logged in, and the `accountId` is saved in a persisted way, for
example in a cookie.
Resolve the `accountId` from the cookie and
call [GetCustomerByAccountId](/api-reference/services/customerservice/openapi/customers/getcustomerbyaccountid).
The method returns a `Customer` object if everything is alright and `null` if the account has been disabled or does not
exist.
## Forgotten password
(or change a password)

1. When the user has forgotten their password they visit a page where they provide some account information. It could be
the email address, customer code or the login name.
2. The back-end calls Norce Commerce Customer Service to fetch the `Customer` object.
Use [GetCustomerByEmail](/api-reference/services/customerservice/openapi/customers/getcustomerbyemail), [GetCustomerByCode](/api-reference/services/customerservice/openapi/customers/getcustomerbycode)
or [GetCustomerByLoginName](/api-reference/services/customerservice/openapi/customers/getcustomerbyloginname)
depending on what data provided by the user. The methods will return the `Customer` object, if it exists and is not
disabled.
3. Your backend generate an email with an encrypted link, containing account name and a valid to timestamp (determines
how long will the link be valid)
4. The user click on the link in the email and lands on a page where the link information is decrypted and validated.
The user is asked for a new password.
5. The backend calls Norce and updates the password. The method
is [UpdateCustomer3](/api-reference/services/customerservice/openapi/customers/updatecustomer3).
Pass in the `Customer` object and the new `password` string.
Note
Customer emails must be unique in Norce. It is not allowed to have two customers with the same email within the same
client or application. (There is a setting to define the scope of uniqueness: customers can either be shared across all
applications or be unique within each application.)
### Notification with a temporary link
When sending out a link to the user where they can change their password, there is a recommended practice to encrypt the
information so that it is not sent as clear texts. Here is an example of how it could look in C#.
details
summary
Here is an example of how it could look in C#.
```csharp
public class PasswordResetHelper
{
///
/// Create the clickable link to send to the users registered email
/// The current timestamp is part of the token
///
public string CreateLinkToTheMail(string loginName)
{
var token = $"{account.LoginName}|{DateTime.Now}";
token = RijndaelEncryption.EncryptToUrl(token);
return $"{PathHelper.FullBaseUrl()}login;token={token}";
}
///
/// Resolve the login name from the token in the link.
///
/// LoginName
public string ResolveLinkFromMail(string token)
{
token = RijndaelEncryption.DecryptFromUrl(token);
var parts = token.Split('|');
if (parts.Length != 2)
throw new Exception("Bad token");
var accountName = parts[0];
DateTime date;
if (!DateTime.TryParse(parts[1], out date))
{
throw new Exception("Bad token");
}
if (DateTime.Now - date > TimeSpan.FromHours(24))
{
throw new Exception("Change password mail is older than 24 hours.");
}
return accountName;
}
}
```
## Suggested further reading
- [Customer in Norce Commerce Services](/api-reference/services/customerservice/openapi)