I set up a basic ASP.NET Core 8 Web API controller using AspNetCore.Identity.MongoDbCore
package to connect to a MongoDB collection, and added a /api/user/{username}
endpoint.
Program.cs
:
using Microsoft.AspNetCore.Identity;
using MongoDB.Bson;
var builder = WebApplication.CreateBuilder(args);
var settings = new DatabaseSettings
{
ConnectionString = Environment.GetEnvironmentVariable("MONGO_CONNECTION_STRING") ?? builder.Configuration.GetSection("Database")["ConnectionString"],
DatabaseName = builder.Configuration.GetSection("Database")["DatabaseName"],
CollectionName = builder.Configuration.GetSection("Database")["CollectionName"]
};
builder.Services.Configure<DatabaseSettings>(options =>
{
options.ConnectionString = settings.ConnectionString;
options.DatabaseName = settings.DatabaseName;
options.CollectionName = settings.CollectionName;
});
builder.Services.AddAuthentication().AddBearerToken(IdentityConstants.BearerScheme);
builder.Services.AddAuthorizationBuilder();
builder.Services.AddIdentityCore<User>().AddApiEndpoints();
builder.Services.AddIdentity<User, Role>()
.AddMongoDbStores<User, Role, ObjectId>
(
settings.ConnectionString,
settings.DatabaseName
)
.AddDefaultTokenProviders();
builder.Services.AddSingleton<UserService>();
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.MapIdentityApi<User>();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.Run();
UserController
:
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly UserService _userService;
public UserController(UserService userService) =>
_userService = userService;
[HttpGet("{username}")]
public async Task<ActionResult<Object>> Get(string username)
{
var user = await _userService.GetAsync(username);
if (user is null)
{
return NotFound();
}
bool isLoggedInUser = User.Identity.IsAuthenticated;
Console.WriteLine(isLoggedInUser);
return new {
user,
isLoggedInUser
};
}
}
UserService
:
public class UserService
{
private readonly IMongoCollection<User> _collection;
public UserService(
IOptions<DatabaseSettings> DatabaseSettings)
{
var mongoClient = new MongoClient(
DatabaseSettings.Value.ConnectionString);
var mongoDatabase = mongoClient.GetDatabase(
DatabaseSettings.Value.DatabaseName);
_collection = mongoDatabase.GetCollection<User>(
DatabaseSettings.Value.CollectionName);
}
public async Task<User?> GetAsync(string username) =>
await _collection.Find(x => x.UserName == username).FirstOrDefaultAsync();
}
I then create a next.js front end and added a login page and a /{username}
page
Login
function:
'use client'
import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
const Login = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const router = useRouter();
useEffect(() => {
const token = localStorage.getItem('token');
if (token) {
router.push('/');
}
}, [router]);
const handleSubmit = async (event) => {
event.preventDefault();
setError('');
const response = await fetch('http://127.0.0.1:5109/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password }),
});
if (response.ok) {
const data = await response.json();
console.log(data);
localStorage.setItem('accessToken', data.accessToken);
router.push(`/`);
} else {
setError('Login failed. Please check your username and password.');
}
};
/{username}
function
const UserDashboard = ({ params }) => {
const { username } = params;
const [user, setUser] = useState(null);
useEffect(() => {
const fetchUser = async () => {
const token = localStorage.getItem('token');
if (!token) {
console.error('No token found in local storage');
return;
}
try {
const res = await fetch(`http://127.0.0.1:5109/api/user/${username}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
}
});
if (res.ok) {
const data = await res.json();
console.log(`Requested Username: ${username}, Is Logged In User: ${data.isLoggedInUser}`);
setUser(data.user);
} else {
console.error('Failed to fetch user data, response not OK');
}
} catch (error) {
console.error('Failed to fetch user data:', error);
}
};
When I check the requests to the API, I could see that it’s passing the bearer token, but both the browser console and the .NET console print out that the user is not logged in.
How can a user log in properly?