diff --git a/src/bp-core/bp-core-actions.php b/src/bp-core/bp-core-actions.php
index d8fc1d6..05786b3 100644
--- a/src/bp-core/bp-core-actions.php
+++ b/src/bp-core/bp-core-actions.php
@@ -117,3 +117,6 @@ add_action( 'bp_activation', 'bp_add_activation_redirect' );
 
 // Email unsubscribe.
 add_action( 'bp_get_request_unsubscribe', 'bp_email_unsubscribe_handler' );
+
+// Login screen pass-through for currently logged-in members.
+add_action( 'login_init', 'bp_login_redirector', 1 );
diff --git a/src/bp-core/bp-core-functions.php b/src/bp-core/bp-core-functions.php
index 5dae2bc..32d3460 100644
--- a/src/bp-core/bp-core-functions.php
+++ b/src/bp-core/bp-core-functions.php
@@ -3775,3 +3775,31 @@ function bp_email_get_unsubscribe_link( $args ) {
 function bp_email_get_salt() {
 	return bp_get_option( 'bp-emails-unsubscribe-salt', null );
 }
+
+/**
+ * Login redirector.
+ *
+ * If a link is not publicly available, we can send members from external
+ * locations, like following links in an email, through the login screen.
+ *
+ * If a user clicks on this link and is already logged in, we should attempt
+ * to redirect the user to the authorized content instead of forcing the user
+ * to re-authenticate.
+ *
+ * @since 2.9.0
+ */
+function bp_login_redirector() {
+	// Redirect links must include the `redirect_to` and `auth` parameters.
+	if ( empty( $_GET['redirect_to'] ) || empty( $_GET['auth'] ) ) {
+		return;
+	}
+
+	/*
+	 * If the user is already logged in,
+	 * skip the login form and redirect them to the content.
+	 */
+	if ( bp_loggedin_user_id() ) {
+		wp_safe_redirect( esc_url_raw( $_GET['redirect_to'] ) );
+		exit;
+	}
+}
\ No newline at end of file
diff --git a/src/bp-messages/bp-messages-functions.php b/src/bp-messages/bp-messages-functions.php
index 4e78ea6..1341ee0 100644
--- a/src/bp-messages/bp-messages-functions.php
+++ b/src/bp-messages/bp-messages-functions.php
@@ -603,10 +603,20 @@ function messages_notification_new_message( $raw_args = array() ) {
 			'notification_type' => 'messages-unread',
 		);
 
+		// Send the user to the message thread via the login screen.
+		$message_url = add_query_arg(
+			array(
+				'action'      => 'bpnoaccess',
+				'auth'        => 1,
+				'redirect_to' => urlencode( bp_core_get_user_domain( $recipient->user_id ) . bp_get_messages_slug() . '/view/' . $thread_id . '/' )
+			),
+			wp_login_url()
+		);
+
 		$args = array(
 			'tokens' => array(
 				'usermessage' => wp_strip_all_tags( stripslashes( $message ) ),
-				'message.url' => esc_url( bp_core_get_user_domain( $recipient->user_id ) . bp_get_messages_slug() . '/view/' . $thread_id . '/' ),
+				'message.url' => esc_url( $message_url ),
 				'sender.name' => $sender_name,
 				'usersubject' => sanitize_text_field( stripslashes( $subject ) ),
 				'unsubscribe' => esc_url( bp_email_get_unsubscribe_link( $unsubscribe_args ) ),
