The simplest solution is to use Cloudfront to create a distribution for your S3 bucket.
You can set up a Cloudfront distribution to only give access with signed URL. This signed URL will work for GET and HEAD request.
The method to sign your URL is different but there's some examples : https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateCFSignatureCodeAndExamples.html