Reputation: 1130
I am developing an OTP based authentication model. below are the back-end and front-end logic
serializers.py
class LoginSerializer(serializers.Serializer):
email = serializers.EmailField()
otp = serializers.CharField()
def validate(self, data):
email = data.get('email')
otp = data.get('otp')
# Logging the initial validation step
api_log(msg="Starting validation")
# Check if email exists
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
raise serializers.ValidationError(
{
"email": "Email does not exist."
}
)
if user.otp != otp:
raise serializers.ValidationError(
{
"otp": "OTP is invalid or expired."
}
)
if User.otp_expiry and User.otp_expiry < timezone.now():
raise serializers.ValidationError(
{
"otp": "OTP is expired."
}
)
# Attach user to validated data
data['user'] = User
return data
views.py
class LoginView(KnoxLoginView):
# @csrf_exempt
def post(self, request, *args, **kwargs):
serializer = LoginSerializer(data=request.data)
api_log(msg=f"login view serializers : {serializer}")
if serializer.is_valid():
user = serializer.validated_data['user']
api_log(msg=f"login view USER : {user}")
# Invalidate the OTP
user.otp = None
user.otp_expiry = None
user.save()
# Create auth token
_, token = AuthToken.objects.create(user)
api_log(msg=f"login view TOKEN : {token}")
return Response({'token': token}, status=status.HTTP_200_OK)
else:
return Response({'error': serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
<form id="login-form">
{% csrf_token %}
<div class="form-group">
<h1>Login</h1>
<p>Please enter your email and OTP to login.</p>
<hr>
<label for="email"><b>Email</b></label>
<input type="text" placeholder="Enter Email" name="email" id="email" required><br>
<label for="otp"><b>OTP</b></label>
<input type="text" placeholder="Enter OTP" name="otp" id="otp" required>
<hr>
<br></br>
<button type="submit" class="loginbtn" id="login-btn">Login</button>
<div id="login-response"></div>
</div>
</form>
<script>
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
const csrftoken = getCookie('csrftoken');
document.getElementById('login-btn').addEventListener('click', function(event) {
event.preventDefault();
const email = document.getElementById('email').value;
const otp = document.getElementById('otp').value;
fetch('{% url "login" %}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrftoken
},
body: JSON.stringify({ email: email, otp: otp })
})
.then(response => {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json();
})
.then(data => {
if (data.token) {
window.location.href = '{% url "home" %}';
} else {
document.getElementById('login-response').innerHTML = `Error: ${data.error}`;
}
})
.catch(error => {
document.getElementById('login-response').innerHTML = `Error: ${error.message}`;
});
});
</script>
</body>
</html>
when I am calling the POST login api in postman,
http://127.0.0.1:8000/auth/login/
I am getting below error
{
"detail": "Authentication credentials were not provided."
}
Since I am also using knox token authentication, so I believe that I need to pass the token that is generated in the response from "inspect" page. I see something like below
csrftoken=W64v4ufsbifnajoUMyFp64S3aemXfCEj
I used this in the postman's headers
csrftoken:W64v4ufsbifnajoUMyFp64S3aemXfCEj
Content-Type:application/json
I see below curl in postman
curl --location 'http://127.0.0.1:8000/auth/login/'
--header 'csrftoken: W64v4ufsbifnajoUMyFp64S3aemXfCEj'
--header 'Content-Type: application/json'
--data-raw '{
"email": "[email protected]",
"otp": "196345"
}'
I receives below error in my IDE console
Forbidden: /auth/login/
[14/Jun/2024 14:29:40] "POST /auth/login/ HTTP/1.1" 403 58
Upvotes: 0
Views: 36